Browse Source

Merge pull request #26 from nameczz/issue-11

Add collection table
ryjiang 4 years ago
parent
commit
bda0b7efe1

+ 6 - 1
client/src/components/status/Types.ts

@@ -7,7 +7,12 @@ export type StatusType = {
   status: StatusEnum;
 };
 
-export type ChildrenStatusType = 'creating' | 'finish' | 'error';
+// @todo need rename
+export enum ChildrenStatusType {
+  CREATING = 'creating',
+  FINISH = 'finish',
+  ERROR = 'error',
+}
 
 export type StatusIconType = {
   type: ChildrenStatusType;

+ 8 - 3
client/src/context/Auth.tsx

@@ -19,9 +19,14 @@ export const AuthProvider = (props: { children: React.ReactNode }) => {
   useEffect(() => {
     const check = async () => {
       const milvusAddress = window.localStorage.getItem(MILVUS_ADDRESS) || '';
-      const res = await MilvusHttp.check(milvusAddress);
-      setAddress(res.data.connected ? milvusAddress : '');
-      if (!res.data.connected) {
+      try {
+        const res = await MilvusHttp.check(milvusAddress);
+        setAddress(res.data.connected ? milvusAddress : '');
+        if (!res.data.connected) {
+          window.localStorage.removeItem(MILVUS_ADDRESS);
+        }
+      } catch (error) {
+        setAddress('');
         window.localStorage.removeItem(MILVUS_ADDRESS);
       }
     };

+ 68 - 0
client/src/http/Collection.ts

@@ -0,0 +1,68 @@
+import { ChildrenStatusType, StatusEnum } from '../components/status/Types';
+import { CollectionView } from '../pages/collections/Types';
+import { IndexState } from '../types/Milvus';
+import BaseModel from './BaseModel';
+
+export class CollectionHttp extends BaseModel implements CollectionView {
+  private autoID!: string;
+  private collection_name!: string;
+  private description!: string;
+  private rowCount!: string;
+  private index_status!: string;
+
+  static COLLECTIONS_URL = '/collections';
+  static COLLECTIONS_INDEX_STATUS_URL = '/collections/indexes/status';
+
+  static CHECK_URL = '/milvus/check';
+
+  constructor(props: CollectionView) {
+    super(props);
+    Object.assign(this, props);
+  }
+
+  static getCollections(): Promise<CollectionHttp[]> {
+    return super.findAll({ path: this.COLLECTIONS_URL, params: {} });
+  }
+
+  static getCollectionsIndexState(): Promise<CollectionHttp[]> {
+    return super.findAll({
+      path: this.COLLECTIONS_INDEX_STATUS_URL,
+      params: {},
+    });
+  }
+
+  get _autoId() {
+    return this.autoID;
+  }
+
+  get _desc() {
+    return this.description;
+  }
+
+  get _id() {
+    return '12';
+  }
+
+  get _name() {
+    return this.collection_name;
+  }
+
+  get _rowCount() {
+    return this.rowCount;
+  }
+
+  get _status() {
+    return StatusEnum.loaded;
+  }
+
+  get _indexState() {
+    switch (this.index_status) {
+      case IndexState.InProgress:
+        return ChildrenStatusType.CREATING;
+      case IndexState.Failed:
+        return ChildrenStatusType.ERROR;
+      default:
+        return ChildrenStatusType.FINISH;
+    }
+  }
+}

+ 42 - 49
client/src/pages/collections/Collections.tsx

@@ -1,4 +1,5 @@
-import { useContext, useEffect, useState } from 'react';
+import { useCallback, useContext, useEffect, useState } from 'react';
+import { Link } from 'react-router-dom';
 import { useNavigationHook } from '../../hooks/Navigation';
 import { ALL_ROUTER_TYPES } from '../../router/Types';
 import MilvusGrid from '../../components/grid';
@@ -10,13 +11,14 @@ import icons from '../../components/icons/Icons';
 import EmptyCard from '../../components/cards/EmptyCard';
 import Status from '../../components/status/Status';
 import { useTranslation } from 'react-i18next';
-import { StatusEnum } from '../../components/status/Types';
-import { makeStyles, Theme, Link, Typography } from '@material-ui/core';
+import { ChildrenStatusType, StatusEnum } from '../../components/status/Types';
+import { makeStyles, Theme, Typography } from '@material-ui/core';
 import StatusIcon from '../../components/status/StatusIcon';
 import CustomToolTip from '../../components/customToolTip/CustomToolTip';
 import { rootContext } from '../../context/Root';
 import CreateCollection from './Create';
 import DeleteTemplate from '../../components/customDialog/DeleteDialogTemplate';
+import { CollectionHttp } from '../../http/Collection';
 
 const useStyles = makeStyles((theme: Theme) => ({
   emptyWrapper: {
@@ -32,10 +34,14 @@ const useStyles = makeStyles((theme: Theme) => ({
     lineHeight: '24px',
     fontSize: '16px',
   },
+  link: {
+    color: theme.palette.common.black,
+  },
 }));
 
 const Collections = () => {
   useNavigationHook(ALL_ROUTER_TYPES.COLLECTIONS);
+
   const {
     pageSize,
     currentPage,
@@ -63,47 +69,34 @@ const Collections = () => {
   const ReleaseIcon = icons.release;
   const InfoIcon = icons.info;
 
+  const fetchData = useCallback(async () => {
+    const res = await CollectionHttp.getCollections();
+    const statusRes = await CollectionHttp.getCollectionsIndexState();
+    setCollections(
+      res.map(v => {
+        const indexStatus = statusRes.find(item => item._name === v._name);
+        Object.assign(v, {
+          nameElement: (
+            <Link to={`/collections/${v._name}`} className={classes.link}>
+              {v._name}
+            </Link>
+          ),
+          statusElement: <Status status={v._status} />,
+          indexCreatingElement: (
+            <StatusIcon
+              type={indexStatus?._indexState || ChildrenStatusType.FINISH}
+            />
+          ),
+        });
+
+        return v;
+      })
+    );
+  }, [classes.link]);
+
   useEffect(() => {
-    const mockCollections: CollectionView[] = [
-      {
-        name: 'collection_1',
-        nameElement: (
-          <Link
-            href="/collection/collection_1"
-            underline="always"
-            color="textPrimary"
-          >
-            collection_1
-          </Link>
-        ),
-        id: 'c1',
-        status: StatusEnum.unloaded,
-        statusElement: <Status status={StatusEnum.unloaded} />,
-        rowCount: '200,000',
-        desc: 'description',
-        indexCreatingElement: <StatusIcon type="creating" />,
-      },
-      {
-        name: 'collection_2',
-        nameElement: (
-          <Link
-            href="/collection/collection_2"
-            underline="always"
-            color="textPrimary"
-          >
-            collection_2
-          </Link>
-        ),
-        id: 'c2',
-        status: StatusEnum.loaded,
-        statusElement: <Status status={StatusEnum.loaded} />,
-        rowCount: '300,000',
-        desc: 'description 2',
-        indexCreatingElement: <StatusIcon type="finish" />,
-      },
-    ];
-    setCollections(mockCollections);
-  }, []);
+    fetchData();
+  }, [fetchData]);
 
   const handleCreateCollection = (param: CollectionCreateParam) => {
     handleCloseDialog();
@@ -119,7 +112,7 @@ const Collections = () => {
 
   const handleAction = (data: CollectionView) => {
     const actionType: 'release' | 'load' =
-      data.status === StatusEnum.loaded ? 'release' : 'load';
+      data._status === StatusEnum.loaded ? 'release' : 'load';
 
     const actionsMap = {
       release: {
@@ -199,7 +192,7 @@ const Collections = () => {
 
   const colDefinitions: ColDefinitionsType[] = [
     {
-      id: 'id',
+      id: '_id',
       align: 'left',
       disablePadding: true,
       label: t('id'),
@@ -217,7 +210,7 @@ const Collections = () => {
       label: t('status'),
     },
     {
-      id: 'rowCount',
+      id: '_rowCount',
       align: 'left',
       disablePadding: false,
       label: (
@@ -230,7 +223,7 @@ const Collections = () => {
       ),
     },
     {
-      id: 'desc',
+      id: '_desc',
       align: 'left',
       disablePadding: false,
       label: t('desc'),
@@ -257,9 +250,9 @@ const Collections = () => {
           label: 'load',
           showIconMethod: 'renderFn',
           getLabel: (row: CollectionView) =>
-            row.status === StatusEnum.loaded ? 'release' : 'load',
+            row._status === StatusEnum.loaded ? 'release' : 'load',
           renderIconFn: (row: CollectionView) =>
-            row.status === StatusEnum.loaded ? <ReleaseIcon /> : <LoadIcon />,
+            row._status === StatusEnum.loaded ? <ReleaseIcon /> : <LoadIcon />,
         },
       ],
     },

+ 14 - 10
client/src/pages/collections/Types.ts

@@ -1,15 +1,19 @@
 import { Dispatch, ReactElement, SetStateAction } from 'react';
-import { StatusEnum } from '../../components/status/Types';
+import { ChildrenStatusType, StatusEnum } from '../../components/status/Types';
 
-export interface CollectionView {
-  name: string;
-  nameElement: ReactElement;
-  id: string;
-  status: StatusEnum;
-  statusElement: ReactElement;
-  rowCount: string;
-  desc: string;
-  indexCreatingElement: ReactElement;
+export interface CollectionData {
+  _name: string;
+  _id: string;
+  _status: StatusEnum;
+  _rowCount: string;
+  _desc: string;
+  _indexState: ChildrenStatusType;
+}
+
+export interface CollectionView extends CollectionData {
+  nameElement?: ReactElement;
+  statusElement?: ReactElement;
+  indexCreatingElement?: ReactElement;
 }
 
 export interface CollectionCreateProps {

+ 1 - 1
client/src/router/Config.ts

@@ -22,7 +22,7 @@ const RouterConfig: RouterConfigType[] = [
     auth: true,
   },
   {
-    path: '/collection/:collectionName',
+    path: '/collections/:collectionName',
     component: Collection,
     auth: true,
   },

+ 7 - 0
client/src/types/Milvus.ts

@@ -0,0 +1,7 @@
+export enum IndexState {
+  IndexStateNone = 'IndexStateNone',
+  Unissued = 'Unissued',
+  InProgress = 'InProgress',
+  Finished = 'Finished',
+  Failed = 'Failed',
+}

+ 2 - 2
server/src/collections/collections.service.ts

@@ -105,8 +105,8 @@ export class CollectionsService {
       for (const name of res.collection_names) {
         const indexRes = await this.getIndexStatus({ collection_name: name });
         data.push({
-          collectionName: name,
-          indexState: indexRes.state,
+          collection_name: name,
+          index_state: indexRes.state,
         });
       }
     }

+ 6 - 2
server/src/milvus/milvus.service.ts

@@ -22,10 +22,10 @@ export class MilvusService {
   async connectMilvus(address: string) {
     try {
       this.milvusClient = new MilvusNode(address);
-      this.milvusAddress = address;
       await this.milvusClient.hasCollection({
         collection_name: 'not_exist',
       });
+      this.milvusAddress = address;
       return { address: this.milvusAddress };
     } catch (error) {
       throw new Error('Connect milvus failed, check your milvus address.');
@@ -33,8 +33,12 @@ export class MilvusService {
   }
 
   async checkConnect(address: string) {
+    if (address !== this.milvusAddress) {
+      return { connected: false };
+    }
+    const res = await this.connectMilvus(address);
     return {
-      connected: this.milvusAddress ? this.milvusAddress === address : false,
+      connected: res.address ? true : false,
     };
   }
 }