Browse Source

update UI for managed database

Signed-off-by: ryjiang <jiangruiyi@gmail.com>
ryjiang 1 year ago
parent
commit
97badd5b2d

+ 34 - 2
client/src/components/icons/Icons.tsx

@@ -3,7 +3,7 @@ import { IconsType } from './Types';
 import { SvgIcon } from '@material-ui/core';
 import { SvgIcon } from '@material-ui/core';
 import AppsIcon from '@material-ui/icons/Apps';
 import AppsIcon from '@material-ui/icons/Apps';
 import CancelIcon from '@material-ui/icons/Cancel';
 import CancelIcon from '@material-ui/icons/Cancel';
-import ZillizIcon from '@/assets/icons/attu.svg?react';
+import AttuIcon from '@/assets/icons/attu.svg?react';
 import ConsoleIcon from '@/assets/icons/console.svg?react';
 import ConsoleIcon from '@/assets/icons/console.svg?react';
 import KeyIcon from '@/assets/icons/key.svg?react';
 import KeyIcon from '@/assets/icons/key.svg?react';
 import SearchEmptyIcon from '@/assets/icons/search.svg?react';
 import SearchEmptyIcon from '@/assets/icons/search.svg?react';
@@ -316,8 +316,40 @@ const icons: { [x in IconsType]: (props?: any) => React.ReactElement } = {
     </SvgIcon>
     </SvgIcon>
   ),
   ),
 
 
+  attu: (props = {}) => (
+    <SvgIcon viewBox="0 0 36 36" component={AttuIcon} {...props} />
+  ),
   zilliz: (props = {}) => (
   zilliz: (props = {}) => (
-    <SvgIcon viewBox="0 0 36 36" component={ZillizIcon} {...props} />
+    <svg
+      width="24"
+      height="24"
+      viewBox="0 0 400 400"
+      fill="none"
+      xmlns="http://www.w3.org/2000/svg"
+    >
+      <path
+        fillRule="evenodd"
+        clipRule="evenodd"
+        d="M187.5 271.942V400H212.5V246.651L278.978 361.793C286.5 358.114 293.728 353.926 300.617 349.274L227.846 223.23L307.986 252.399C311.602 244.961 314.472 237.093 316.499 228.893L271.46 212.5H400V187.5H246.65L361.793 121.022C358.114 113.499 353.926 106.271 349.274 99.3824L223.977 171.723L252.899 92.2593C245.477 88.6082 237.622 85.7015 229.433 83.6365L212.5 130.16V0H187.5V153.349L121.022 38.2061C113.5 41.8851 106.271 46.0732 99.3827 50.7256L171.852 176.245L92.1862 147.25C88.5455 154.677 85.6496 162.535 83.5959 170.727L129.678 187.5H0V212.5H153.349L38.2063 278.977C41.8852 286.5 46.0734 293.728 50.7258 300.617L176.992 227.717L147.75 308.058C155.193 311.664 163.065 314.523 171.268 316.539L187.5 271.942Z"
+        fill="url(#paint0_linear_3354_2834)"
+      />
+      <defs>
+        <linearGradient
+          id="paint0_linear_3354_2834"
+          x1="85"
+          y1="42.5"
+          x2="292"
+          y2="378"
+          gradientUnits="userSpaceOnUse"
+        >
+          <stop stopColor="#E88DEA" />
+          <stop offset="0.187967" stopColor="#9D41FF" />
+          <stop offset="0.531725" stopColor="#2858FF" />
+          <stop offset="0.844232" stopColor="#29B8FF" />
+          <stop offset="1" stopColor="#3DCBF9" />
+        </linearGradient>
+      </defs>
+    </svg>
   ),
   ),
   refresh: (props = {}) => (
   refresh: (props = {}) => (
     <svg
     <svg

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

@@ -1,4 +1,6 @@
 export type IconsType =
 export type IconsType =
+  | 'zilliz'
+  | 'attu'
   | 'search'
   | 'search'
   | 'add'
   | 'add'
   | 'addOutline'
   | 'addOutline'
@@ -9,7 +11,6 @@ export type IconsType =
   | 'error'
   | 'error'
   | 'clear'
   | 'clear'
   | 'app'
   | 'app'
-  | 'zilliz'
   | 'navOverview'
   | 'navOverview'
   | 'navCollection'
   | 'navCollection'
   | 'navConsole'
   | 'navConsole'

+ 1 - 1
client/src/components/menu/NavMenu.tsx

@@ -185,7 +185,7 @@ const NavMenu: FC<NavMenuType> = props => {
     );
     );
   };
   };
 
 
-  const Logo = icons.zilliz;
+  const Logo = icons.attu;
   const ExpandIcon = icons.expand;
   const ExpandIcon = icons.expand;
 
 
   return (
   return (

+ 4 - 1
client/src/context/Auth.tsx

@@ -35,6 +35,9 @@ export const AuthProvider = (props: { children: React.ReactNode }) => {
 
 
   useEffect(() => {
   useEffect(() => {
     document.title = address ? `${address} - Attu` : 'Attu';
     document.title = address ? `${address} - Attu` : 'Attu';
+    return () => {
+      document.title = 'Attu';
+    }
   }, [address, username]);
   }, [address, username]);
 
 
   const logout = () => {
   const logout = () => {
@@ -60,7 +63,7 @@ export const AuthProvider = (props: { children: React.ReactNode }) => {
         setIsAuth,
         setIsAuth,
         setClientId,
         setClientId,
         logout,
         logout,
-        isManaged: address.includes('vectordb.zillizcloud.com'),
+        isManaged: address.includes('zilliz'),
       }}
       }}
     >
     >
       {props.children}
       {props.children}

+ 4 - 4
client/src/context/Data.tsx

@@ -143,10 +143,10 @@ export const DataProvider = (props: { children: React.ReactNode }) => {
   );
   );
 
 
   // API: fetch databases
   // API: fetch databases
-  const fetchDatabases = async () => {
-    setLoadingDatabases(true);
+  const fetchDatabases = async (updateLoading?: boolean) => {
+    updateLoading && setLoadingDatabases(true);
     const newDatabases = await DatabaseService.listDatabases();
     const newDatabases = await DatabaseService.listDatabases();
-    setLoadingDatabases(false);
+    updateLoading && setLoadingDatabases(false);
 
 
     // if no database, logout
     // if no database, logout
     if (newDatabases.length === 0) {
     if (newDatabases.length === 0) {
@@ -331,7 +331,7 @@ export const DataProvider = (props: { children: React.ReactNode }) => {
       socket.current.on('connect', async () => {
       socket.current.on('connect', async () => {
         console.log('--- ws connected ---', clientId);
         console.log('--- ws connected ---', clientId);
         // fetch db
         // fetch db
-        await fetchDatabases();
+        await fetchDatabases(true);
         // set connected to trues
         // set connected to trues
         setConnected(true);
         setConnected(true);
       });
       });

+ 1 - 1
client/src/context/System.tsx

@@ -50,7 +50,7 @@ export const SystemProvider = (props: { children: React.ReactNode }) => {
 
 
       // get system config
       // get system config
       const systemConfig = getSystemConfigs(parsedJson.workingNodes);
       const systemConfig = getSystemConfigs(parsedJson.workingNodes);
-      const deployMode = rootCoord.infos.system_info.deploy_mode;
+      const deployMode = rootCoord.infos.system_info?.deploy_mode;
       const systemInfo = rootCoord.infos.system_info;
       const systemInfo = rootCoord.infos.system_info;
 
 
       const data = {
       const data = {

+ 18 - 15
client/src/pages/databases/tree/index.tsx

@@ -2,7 +2,7 @@ import { useTranslation } from 'react-i18next';
 import TreeView from '@material-ui/lab/TreeView';
 import TreeView from '@material-ui/lab/TreeView';
 import TreeItem from '@material-ui/lab/TreeItem';
 import TreeItem from '@material-ui/lab/TreeItem';
 import icons from '@/components/icons/Icons';
 import icons from '@/components/icons/Icons';
-import { makeStyles, Theme, Tooltip } from '@material-ui/core';
+import { makeStyles, Theme, Tooltip, Typography } from '@material-ui/core';
 import { useNavigate, Params } from 'react-router-dom';
 import { useNavigate, Params } from 'react-router-dom';
 import { CollectionObject } from '@server/types';
 import { CollectionObject } from '@server/types';
 import clcx from 'clsx';
 import clcx from 'clsx';
@@ -48,7 +48,7 @@ const useStyles = makeStyles((theme: Theme) => ({
     '& .MuiTreeItem-group': {
     '& .MuiTreeItem-group': {
       marginLeft: 0,
       marginLeft: 0,
       '& .MuiTreeItem-content': {
       '& .MuiTreeItem-content': {
-        padding: '0 0 0 16px',
+        padding: '0 0 0 8px',
       },
       },
     },
     },
     '& .MuiTreeItem-label:hover': {
     '& .MuiTreeItem-label:hover': {
@@ -87,15 +87,14 @@ const useStyles = makeStyles((theme: Theme) => ({
     },
     },
   },
   },
   collectionNode: {
   collectionNode: {
-    display: 'flex',
-    justifyContent: 'space-between',
     minHeight: '24px',
     minHeight: '24px',
     lineHeight: '24px',
     lineHeight: '24px',
+    position: 'relative',
   },
   },
-  right: {
+  collectionName: {
     display: 'flex',
     display: 'flex',
     alignItems: 'center',
     alignItems: 'center',
-    width: 20,
+    width: 'calc(100% - 50px)',
   },
   },
   count: {
   count: {
     fontSize: '13px',
     fontSize: '13px',
@@ -107,8 +106,10 @@ const useStyles = makeStyles((theme: Theme) => ({
     width: '8px',
     width: '8px',
     height: '8px',
     height: '8px',
     borderRadius: '50%',
     borderRadius: '50%',
-    position: 'relative',
-    top: '0',
+    position: 'absolute',
+    left: 160,
+    top: 8,
+    zIndex: 1,
   },
   },
   loaded: {
   loaded: {
     border: `1px solid ${theme.palette.primary.main}`,
     border: `1px solid ${theme.palette.primary.main}`,
@@ -154,15 +155,17 @@ const CollectionNode: React.FC<{ data: CollectionObject }> = ({ data }) => {
 
 
   return (
   return (
     <div className={classes.collectionNode}>
     <div className={classes.collectionNode}>
-      <div>
-        {data.collection_name}
-        <span className={classes.count}>({formatNumber(data.rowCount || 0)})</span>
-      </div>
-      <div className={classes.right}>
-        <Tooltip title={loadStatus}>
-          <div className={loadClass}></div>
+      <div className={classes.collectionName}>
+        <Tooltip title={data.collection_name}>
+          <Typography noWrap>{data.collection_name}</Typography>
         </Tooltip>
         </Tooltip>
+        <span className={classes.count}>
+          ({formatNumber(data.rowCount || 0)})
+        </span>
       </div>
       </div>
+      <Tooltip title={loadStatus}>
+        <div className={loadClass}></div>
+      </Tooltip>
     </div>
     </div>
   );
   );
 };
 };

+ 9 - 5
client/src/pages/overview/DatabaseCard.tsx

@@ -6,7 +6,7 @@ import { MilvusService } from '@/http';
 import icons from '@/components/icons/Icons';
 import icons from '@/components/icons/Icons';
 import CustomButton from '@/components/customButton/CustomButton';
 import CustomButton from '@/components/customButton/CustomButton';
 import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
 import DeleteTemplate from '@/components/customDialog/DeleteDialogTemplate';
-import { rootContext } from '@/context';
+import { rootContext, authContext } from '@/context';
 import { DatabaseObject } from '@server/types';
 import { DatabaseObject } from '@server/types';
 import CreateDatabaseDialog from '../dialogs/CreateDatabaseDialog';
 import CreateDatabaseDialog from '../dialogs/CreateDatabaseDialog';
 
 
@@ -83,21 +83,25 @@ const DatabaseCard: FC<DatabaseCardProps> = ({
   setDatabase,
   setDatabase,
   dropDatabase,
   dropDatabase,
 }) => {
 }) => {
+  // context
+  const { isManaged } = useContext(authContext);
+  const { setDialog, openSnackBar, handleCloseDialog } =
+    useContext(rootContext);
+
+  // i18n
   const { t: overviewTrans } = useTranslation('overview');
   const { t: overviewTrans } = useTranslation('overview');
   const { t: successTrans } = useTranslation('success');
   const { t: successTrans } = useTranslation('success');
   const { t: dbTrans } = useTranslation('database');
   const { t: dbTrans } = useTranslation('database');
   const { t: btnTrans } = useTranslation('btn');
   const { t: btnTrans } = useTranslation('btn');
   const { t: dialogTrans } = useTranslation('dialog');
   const { t: dialogTrans } = useTranslation('dialog');
 
 
-  const { setDialog, openSnackBar, handleCloseDialog } =
-    useContext(rootContext);
-
   const navigation = useNavigate();
   const navigation = useNavigate();
   const classes = useStyles();
   const classes = useStyles();
   const theme = useTheme();
   const theme = useTheme();
   const DbIcon = icons.database;
   const DbIcon = icons.database;
   const DeleteIcon = icons.delete;
   const DeleteIcon = icons.delete;
   const PlusIcon = icons.add;
   const PlusIcon = icons.add;
+  const ZillizIcon = icons.zilliz;
 
 
   const onClick = async () => {
   const onClick = async () => {
     // use database
     // use database
@@ -141,7 +145,7 @@ const DatabaseCard: FC<DatabaseCardProps> = ({
     <section className={`${wrapperClass}`}>
     <section className={`${wrapperClass}`}>
       <section className={`${classes.wrapper}`} onClick={onClick}>
       <section className={`${classes.wrapper}`} onClick={onClick}>
         <Typography variant="h3" className={classes.dbTitle}>
         <Typography variant="h3" className={classes.dbTitle}>
-          <DbIcon /> {database.name}
+          {isManaged ? <ZillizIcon /> : <DbIcon />} {database.name}
         </Typography>
         </Typography>
         <div>
         <div>
           <div key={database.name}>
           <div key={database.name}>

+ 3 - 3
client/src/utils/Metric.ts

@@ -36,10 +36,10 @@ export const parseJson = (jsonData: any) => {
       childNodes.push(node);
       childNodes.push(node);
     }
     }
 
 
-    const info = node.infos.hardware_infos;
-    system.memory += info.memory;
+    const info = node.infos.hardware_infos || {};
+    system.memory += info.memory || 0;
     system.memoryUsage += info.memory_usage;
     system.memoryUsage += info.memory_usage;
-    system.disk += info.disk;
+    system.disk += info.disk || 0;
     system.diskUsage += info.disk_usage;
     system.diskUsage += info.disk_usage;
   });
   });
   return { nodes, childNodes, system, workingNodes, allNodes };
   return { nodes, childNodes, system, workingNodes, allNodes };