Browse Source

update layout

tumao 4 years ago
parent
commit
84dbe6dd01

+ 7 - 1
client/src/App.tsx

@@ -1,10 +1,16 @@
 import Router from './router/Router';
 import { RootProvider } from './context/Root';
+import { NavProvider } from './context/Navigation';
+import { AuthProvider } from './context/Auth';
 
 function App() {
   return (
     <RootProvider>
-      <Router></Router>
+      <AuthProvider>
+        <NavProvider>
+          <Router></Router>
+        </NavProvider>
+      </AuthProvider>
     </RootProvider>
   );
 }

+ 4 - 1
client/src/components/icons/Icons.tsx

@@ -14,7 +14,8 @@ import CancelIcon from '@material-ui/icons/Cancel';
 import CheckCircleIcon from '@material-ui/icons/CheckCircle';
 import ExpandLess from '@material-ui/icons/ExpandLess';
 import ExpandMore from '@material-ui/icons/ExpandMore';
-
+import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';
+import ExitToAppIcon from '@material-ui/icons/ExitToApp';
 import { SvgIcon } from '@material-ui/core';
 import { ReactComponent as MilvusIcon } from '../../assets/icons/milvus.svg';
 import { ReactComponent as OverviewIcon } from '../../assets/icons/overview.svg';
@@ -36,6 +37,8 @@ const icons: { [x in IconsType]: (props?: any) => React.ReactElement } = {
   success: (props = {}) => <CheckCircleIcon {...props} />,
   expandLess: (props = {}) => <ExpandLess {...props} />,
   expandMore: (props = {}) => <ExpandMore {...props} />,
+  back: (props = {}) => <ArrowBackIosIcon {...props} />,
+  logout: (props = {}) => <ExitToAppIcon {...props} />,
 
   milvus: (props = {}) => (
     <SvgIcon viewBox="0 0 44 31" component={MilvusIcon} {...props} />

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

@@ -16,4 +16,6 @@ export type IconsType =
   | 'navCollection'
   | 'navConsole'
   | 'expandLess'
-  | 'expandMore';
+  | 'expandMore'
+  | 'back'
+  | 'logout';

+ 91 - 4
client/src/components/layout/Header.tsx

@@ -1,7 +1,11 @@
-import { FC } from 'react';
-import { makeStyles, Theme, createStyles } from '@material-ui/core';
+import { FC, useContext } from 'react';
+import { makeStyles, Theme, createStyles, Typography } from '@material-ui/core';
 import { HeaderType } from './Types';
-// import { useTranslation } from 'react-i18next';
+import { navContext } from '../../context/Navigation';
+import icons from '../icons/Icons';
+import { useHistory } from 'react-router-dom';
+import { authContext } from '../../context/Auth';
+import { useTranslation } from 'react-i18next';
 
 const useStyles = makeStyles((theme: Theme) =>
   createStyles({
@@ -11,13 +15,96 @@ const useStyles = makeStyles((theme: Theme) =>
       color: theme.palette.common.black,
       marginRight: theme.spacing(5),
     },
+    contentWrapper: {
+      display: 'flex',
+      justifyContent: 'space-between',
+      alignItems: 'center',
+      paddingTop: theme.spacing(3),
+      paddingLeft: theme.spacing(6),
+      flex: 1,
+    },
+    navigation: {
+      display: 'flex',
+      alignItems: 'center',
+      fontWeight: 'bold',
+    },
+    icon: {
+      color: theme.palette.primary.main,
+      cursor: 'pointer',
+    },
+    addressWrapper: {
+      display: 'flex',
+      alignItems: 'center',
+
+      '& .text': {
+        marginRight: theme.spacing(3),
+
+        '& p': {
+          margin: 0,
+        },
+
+        '& .address': {
+          fontSize: '14px',
+          lineHeight: '20px',
+          color: '#545454',
+        },
+
+        '& .status': {
+          fontSize: '12px',
+          lineHeight: '16px',
+          color: '#1ba954',
+          textTransform: 'capitalize',
+        },
+      },
+    },
   })
 );
 
 const Header: FC<HeaderType> = props => {
   const classes = useStyles();
+  const { navInfo } = useContext(navContext);
+  const { address, setIsAuth, setAddress } = useContext(authContext);
+  const history = useHistory();
+  const { t } = useTranslation();
+  const statusTrans: { [key in string]: string } = t('status');
+  const BackIcon = icons.back;
+  const LogoutIcon = icons.logout;
+
+  const handleBack = (path: string) => {
+    history.push(path);
+  };
+
+  const handleLogout = () => {
+    setAddress('');
+    setIsAuth(false);
+  };
+
+  return (
+    <header className={classes.header}>
+      <div className={classes.contentWrapper}>
+        <div className={classes.navigation}>
+          {navInfo.backPath !== '' && (
+            <BackIcon
+              classes={{ root: classes.icon }}
+              onClick={() => handleBack(navInfo.backPath)}
+            />
+          )}
+
+          <Typography variant="h4" color="textPrimary">
+            {navInfo.navTitle}
+          </Typography>
+        </div>
 
-  return <header className={classes.header}>header</header>;
+        <div className={classes.addressWrapper}>
+          <div className="text">
+            <p className="address">{address}</p>
+            <p className="status">{statusTrans.running}</p>
+          </div>
+          <LogoutIcon classes={{ root: classes.icon }} onClick={handleLogout} />
+        </div>
+      </div>
+    </header>
+  );
 };
 
 export default Header;

+ 2 - 2
client/src/components/layout/Layout.tsx

@@ -4,10 +4,10 @@ import { makeStyles, Theme, createStyles } from '@material-ui/core';
 import NavMenu from '../menu/NavMenu';
 import { NavMenuItem } from '../menu/Types';
 import { useContext } from 'react';
-import { rootContext } from '../../context/Root';
 import icons from '../icons/Icons';
 import { useTranslation } from 'react-i18next';
 import { useHistory } from 'react-router-dom';
+import { authContext } from '../../context/Auth';
 
 const useStyles = makeStyles((theme: Theme) =>
   createStyles({
@@ -40,7 +40,7 @@ const useStyles = makeStyles((theme: Theme) =>
 
 const Layout = (props: any) => {
   const history = useHistory();
-  const { isAuth } = useContext(rootContext);
+  const { isAuth } = useContext(authContext);
   const { t } = useTranslation('nav');
   const classes = useStyles();
 

+ 0 - 8
client/src/components/menu/NavMenu.tsx

@@ -74,14 +74,6 @@ const useStyles = makeStyles((theme: Theme) =>
     logo: {
       marginRight: theme.spacing(1),
     },
-
-    feedback: {
-      color: theme.palette.primary.main,
-
-      '&:hover': {
-        backgroundColor: '#fff',
-      },
-    },
   })
 );
 

+ 22 - 0
client/src/context/Auth.tsx

@@ -0,0 +1,22 @@
+import { createContext, useState } from 'react';
+import { AuthContextType } from './Types';
+
+export const authContext = createContext<AuthContextType>({
+  isAuth: false,
+  setIsAuth: () => {},
+  address: '',
+  setAddress: () => {},
+});
+
+const { Provider } = authContext;
+
+export const AuthProvider = (props: { children: React.ReactNode }) => {
+  const [isAuth, setIsAuth] = useState<boolean>(false);
+  const [address, setAddress] = useState<string>('');
+
+  return (
+    <Provider value={{ isAuth, setIsAuth, address, setAddress }}>
+      {props.children}
+    </Provider>
+  );
+};

+ 24 - 0
client/src/context/Navigation.tsx

@@ -0,0 +1,24 @@
+import { createContext, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { NavInfo } from '../router/Types';
+import { NavContextType } from './Types';
+
+export const navContext = createContext<NavContextType>({
+  navInfo: {
+    navTitle: '',
+    backPath: '',
+  },
+  setNavInfo: () => {},
+});
+
+const { Provider } = navContext;
+
+export const NavProvider = (props: { children: React.ReactNode }) => {
+  const { t } = useTranslation('nav');
+  const [navInfo, setNavInfo] = useState<NavInfo>({
+    navTitle: t('overview'),
+    backPath: '',
+  });
+
+  return <Provider value={{ navInfo, setNavInfo }}>{props.children}</Provider>;
+};

+ 0 - 6
client/src/context/Root.tsx

@@ -34,8 +34,6 @@ export const rootContext = React.createContext<RootContextType>({
   setDialog: params => {},
   handleCloseDialog: () => {},
   setDrawer: (params: any) => {},
-  isAuth: false,
-  setIsAuth: () => {},
 });
 
 const { Provider } = rootContext;
@@ -67,8 +65,6 @@ export const RootProvider = (props: { children: React.ReactNode }) => {
     child: <></>,
   });
 
-  const [isAuth, setIsAuth] = useState<boolean>(false);
-
   const handleSnackBarClose = () => {
     setSnackBar(v => ({ ...v, open: false }));
   };
@@ -118,8 +114,6 @@ export const RootProvider = (props: { children: React.ReactNode }) => {
         setDialog,
         handleCloseDialog,
         setDrawer,
-        isAuth,
-        setIsAuth,
       }}
     >
       <ThemeProvider theme={theme}>

+ 14 - 2
client/src/context/Types.ts

@@ -1,4 +1,5 @@
 import { Dispatch, ReactElement, SetStateAction } from 'react';
+import { NavInfo } from '../router/Types';
 
 export type RootContextType = {
   openSnackBar: OpenSnackBarType;
@@ -6,8 +7,6 @@ export type RootContextType = {
   setDialog: (params: DialogType) => void;
   handleCloseDialog: () => void;
   setDrawer: (params: any) => void;
-  isAuth: boolean;
-  setIsAuth: Dispatch<SetStateAction<boolean>>;
 };
 
 // this is for any custom dialog
@@ -33,6 +32,7 @@ export type DialogType = {
     containerClass?: string;
   };
 };
+
 export type SnackBarType = {
   open: boolean;
   message: string | ReactElement;
@@ -51,3 +51,15 @@ export type OpenSnackBarType = (
     vertical: 'bottom' | 'top';
   }
 ) => void;
+
+export type AuthContextType = {
+  isAuth: boolean;
+  setIsAuth: Dispatch<SetStateAction<boolean>>;
+  address: string;
+  setAddress: Dispatch<SetStateAction<string>>;
+};
+
+export type NavContextType = {
+  navInfo: NavInfo;
+  setNavInfo: (param: NavInfo) => void;
+};

+ 59 - 0
client/src/hooks/Navigation.ts

@@ -0,0 +1,59 @@
+import { useContext, useEffect } from 'react';
+import { useTranslation } from 'react-i18next';
+import { useParams } from 'react-router';
+import { navContext } from '../context/Navigation';
+import { ALL_ROUTER_TYPES, NavInfo } from '../router/Types';
+
+export const useNavigationHook = (
+  type: ALL_ROUTER_TYPES,
+  extraParam?: {
+    collectionName: string;
+  }
+) => {
+  const { t } = useTranslation('nav');
+  const { setNavInfo } = useContext(navContext);
+
+  const { collectionId = '' } =
+    useParams<{
+      collectionId?: string;
+    }>();
+
+  useEffect(() => {
+    switch (type) {
+      case ALL_ROUTER_TYPES.OVERVIEW: {
+        const navInfo: NavInfo = {
+          navTitle: t('overview'),
+          backPath: '',
+        };
+        setNavInfo(navInfo);
+        break;
+      }
+      case ALL_ROUTER_TYPES.COLLECTIONS: {
+        const navInfo: NavInfo = {
+          navTitle: t('collection'),
+          backPath: '',
+        };
+        setNavInfo(navInfo);
+        break;
+      }
+      case ALL_ROUTER_TYPES.COLLECTION_DETAIL: {
+        const navInfo: NavInfo = {
+          navTitle: extraParam?.collectionName as string,
+          backPath: '/collections',
+        };
+        setNavInfo(navInfo);
+        break;
+      }
+      case ALL_ROUTER_TYPES.CONSOLE: {
+        const navInfo: NavInfo = {
+          navTitle: t('console'),
+          backPath: '',
+        };
+        setNavInfo(navInfo);
+        break;
+      }
+      default:
+        break;
+    }
+  }, [type, extraParam, t, setNavInfo, collectionId]);
+};

+ 4 - 0
client/src/pages/collections/Collections.tsx

@@ -1,4 +1,8 @@
+import { useNavigationHook } from '../../hooks/Navigation';
+import { ALL_ROUTER_TYPES } from '../../router/Types';
+
 const Collections = () => {
+  useNavigationHook(ALL_ROUTER_TYPES.COLLECTIONS);
   return <section>collection</section>;
 };
 

+ 3 - 2
client/src/pages/connect/Connect.tsx

@@ -9,7 +9,7 @@ import { formatForm } from '../../utils/Form';
 import { useFormValidation } from '../../hooks/Form';
 import CustomButton from '../../components/customButton/CustomButton';
 import { useHistory } from 'react-router-dom';
-import { rootContext } from '../../context/Root';
+import { authContext } from '../../context/Auth';
 
 const useStyles = makeStyles((theme: Theme) => ({
   wrapper: {
@@ -41,7 +41,7 @@ const useStyles = makeStyles((theme: Theme) => ({
 
 const Connect = () => {
   const history = useHistory();
-  const { setIsAuth } = useContext(rootContext);
+  const { setIsAuth, setAddress } = useContext(authContext);
   const classes = useStyles();
   const { t } = useTranslation();
   const { t: warningTrans } = useTranslation('warning');
@@ -65,6 +65,7 @@ const Connect = () => {
 
   const handleConnect = () => {
     setIsAuth(true);
+    setAddress(form.address);
     history.push('/');
   };
 

+ 4 - 0
client/src/pages/console/Console.tsx

@@ -1,4 +1,8 @@
+import { useNavigationHook } from '../../hooks/Navigation';
+import { ALL_ROUTER_TYPES } from '../../router/Types';
+
 const Console = () => {
+  useNavigationHook(ALL_ROUTER_TYPES.CONSOLE);
   return <section>console</section>;
 };
 

+ 6 - 26
client/src/pages/overview/Overview.tsx

@@ -1,30 +1,10 @@
-import { useContext } from 'react';
-import { useTranslation } from 'react-i18next';
-import { rootContext } from '../../context/Root';
+import { useNavigationHook } from '../../hooks/Navigation';
+import { ALL_ROUTER_TYPES } from '../../router/Types';
 
-const Dashboard = () => {
-  const { setDialog } = useContext(rootContext);
+const Overview = () => {
+  useNavigationHook(ALL_ROUTER_TYPES.OVERVIEW);
 
-  const openDialog = () => {
-    setDialog({
-      open: true,
-      type: 'notice',
-      params: {
-        title: 'test',
-        component: <></>,
-        confirm: () => new Promise((res, rej) => res(true)),
-        cancel: () => new Promise((res, rej) => res(true)),
-      },
-    });
-  };
-
-  const { t } = useTranslation('btn');
-
-  return (
-    <section>
-      <button onClick={openDialog}>{t('confirm')}</button>
-    </section>
-  );
+  return <section>overview</section>;
 };
 
-export default Dashboard;
+export default Overview;

+ 2 - 2
client/src/router/Router.tsx

@@ -2,14 +2,14 @@ import { Switch, Route, BrowserRouter, Redirect } from 'react-router-dom';
 import routerConfig from './Config';
 import Layout from '../components/layout/Layout';
 import { useContext } from 'react';
-import { rootContext } from '../context/Root';
+import { authContext } from '../context/Auth';
 /**
  * Global responsible for global effect
  * Layout responsible for ui view
  *
  */
 const RouterWrapper = () => {
-  const { isAuth } = useContext(rootContext);
+  const { isAuth } = useContext(authContext);
 
   return (
     <BrowserRouter>

+ 9 - 15
client/src/router/Types.ts

@@ -1,21 +1,15 @@
-export enum ALL_ROUTER_STATES {
-  // '/databases'
-  ALL_DATABASES = 'all_databases',
-  // '/databases/:databaseId'
-  DATABASE_DETAIL = 'database_detail',
-  // '/databases/:databaseId/collections/:collectionId'
+export enum ALL_ROUTER_TYPES {
+  // '/'
+  OVERVIEW = 'overview',
+  // '/collections'
+  COLLECTIONS = 'collections',
+  // '/collections/:collectionId'
   COLLECTION_DETAIL = 'collection_detail',
-  // '/databases/:databaseId/collections/:collectionId/partitions/:partitionId'
-  PARTITION_DETAIL = 'partition_detail',
-  // '/tasks'
-  ALL_TASKS = 'all_tasks',
-  // '/queries'
-  ALL_QUERIES = 'all_queries',
-  // '/queries/:queryId'
-  QUERY_DETAIL = 'query_detail',
+  // '/console'
+  CONSOLE = 'console',
 }
 
 export type NavInfo = {
-  navs: string[];
+  navTitle: string;
   backPath: string;
 };