Skip to content

Commit

Permalink
show user icon with login username in tooltip on header (#326)
Browse files Browse the repository at this point in the history
Co-authored-by: wangsn <wangsn@cn.ibm.com>
  • Loading branch information
techgeniuswang and wangsn authored Nov 29, 2023
1 parent 92ef72d commit 5d606f5
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 9 deletions.
6 changes: 4 additions & 2 deletions client/src/components/layout/GlobalEffect.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { useContext } from 'react';
import axiosInstance from '@/http/Axios';
import { rootContext, authContext } from '@/context';
import { MILVUS_ADDRESS } from '@/consts';
import { MILVUS_ADDRESS, LOGIN_USERNAME } from '@/consts';
import { HTTP_STATUS_CODE } from '@server/utils/Const';

let axiosResInterceptor: number | null = null;
// let timer: Record<string, ReturnType<typeof setTimeout> | number>[] = [];
// we only take side effect here, nothing else
const GlobalEffect = (props: { children: React.ReactNode }) => {
const { openSnackBar } = useContext(rootContext);
const { setIsAuth, setAddress } = useContext(authContext);
const { setIsAuth, setAddress, setUsername } = useContext(authContext);

// catch axios error here
if (axiosResInterceptor === null) {
Expand All @@ -27,7 +27,9 @@ const GlobalEffect = (props: { children: React.ReactNode }) => {
const reset = () => {
setIsAuth(false);
setAddress('');
setUsername('');
window.localStorage.removeItem(MILVUS_ADDRESS);
window.localStorage.removeItem(LOGIN_USERNAME);
};
switch (response.status) {
case HTTP_STATUS_CODE.UNAUTHORIZED:
Expand Down
21 changes: 18 additions & 3 deletions client/src/components/layout/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { FC, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles, Theme, createStyles, Typography } from '@material-ui/core';
import {
makeStyles,
Theme,
createStyles,
Typography,
Tooltip,
} from '@material-ui/core';
import AccountCircleIcon from '@material-ui/icons/AccountCircle';
import { useNavigate } from 'react-router-dom';
import { navContext, dataContext, authContext } from '@/context';
import { MilvusHttp } from '@/http';
import { MILVUS_ADDRESS } from '@/consts';
import { MILVUS_ADDRESS, LOGIN_USERNAME } from '@/consts';
import CustomSelector from '@/components/customSelector/CustomSelector';
import icons from '../icons/Icons';
import { HeaderType } from './Types';
Expand Down Expand Up @@ -65,7 +72,8 @@ const Header: FC<HeaderType> = props => {
const classes = useStyles();
const { navInfo } = useContext(navContext);
const { database, databases, setDatabase } = useContext(dataContext);
const { address, setAddress, setIsAuth } = useContext(authContext);
const { address, setAddress, username, setUsername, setIsAuth } =
useContext(authContext);
const navigate = useNavigate();

const { t: commonTrans } = useTranslation();
Expand All @@ -80,9 +88,11 @@ const Header: FC<HeaderType> = props => {

const handleLogout = async () => {
setAddress('');
setUsername('');
setIsAuth(false);
await MilvusHttp.closeConnection();
window.localStorage.removeItem(MILVUS_ADDRESS);
window.localStorage.removeItem(LOGIN_USERNAME);
// make sure we clear state in all pages
// navigate(0);
};
Expand Down Expand Up @@ -127,6 +137,11 @@ const Header: FC<HeaderType> = props => {
<Typography className="address">{address}</Typography>
<Typography className="status">{statusTrans.running}</Typography>
</div>
{username && (
<Tooltip title={username}>
<AccountCircleIcon classes={{ root: classes.icon }} />
</Tooltip>
)}
<LogoutIcon classes={{ root: classes.icon }} onClick={handleLogout} />
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions client/src/consts/Localstorage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const SESSION = 'CLOUD_SESSION';
export const MILVUS_ADDRESS = 'milvus-address';
export const LOGIN_USERNAME = 'login-username';
export const LAST_TIME_ADDRESS = 'last-time-address';
export const LAST_TIME_DATABASE = 'last-time-database';

Expand Down
20 changes: 17 additions & 3 deletions client/src/context/Auth.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { createContext, useEffect, useState } from 'react';
import { MILVUS_ADDRESS } from '@/consts';
import { MILVUS_ADDRESS, LOGIN_USERNAME } from '@/consts';
import { MilvusHttp } from '@/http';
import { AuthContextType } from './Types';

export const authContext = createContext<AuthContextType>({
isAuth: false,
address: '',
username: '',
isManaged: false,
setAddress: () => {},
setUsername: () => {},
setIsAuth: () => {},
});

Expand All @@ -17,6 +19,10 @@ export const AuthProvider = (props: { children: React.ReactNode }) => {
const [address, setAddress] = useState<string>(
window.localStorage.getItem(MILVUS_ADDRESS) || ''
);
// get login username from local storage
const [username, setUsername] = useState<string>(
window.localStorage.getItem(LOGIN_USERNAME) || ''
);
const [isAuth, setIsAuth] = useState<boolean>(address !== '');
// const isAuth = useMemo(() => !!address, [address]);

Expand All @@ -33,20 +39,28 @@ export const AuthProvider = (props: { children: React.ReactNode }) => {
if (!res.connected) {
window.localStorage.removeItem(MILVUS_ADDRESS);
}

const username = window.localStorage.getItem(LOGIN_USERNAME) || '';
if (!username) {
return;
}
setUsername(username);
};
check();
}, [setAddress]);
}, [setAddress, setUsername]);

useEffect(() => {
document.title = address ? `${address} - Attu` : 'Attu';
}, [address]);
}, [address, username]);

return (
<Provider
value={{
isAuth,
address,
username,
setAddress,
setUsername,
setIsAuth,
isManaged: address.includes('vectordb.zillizcloud.com'),
}}
Expand Down
2 changes: 2 additions & 0 deletions client/src/context/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,10 @@ export type OpenSnackBarType = (
export type AuthContextType = {
isAuth: boolean;
address: string;
username: string;
isManaged: boolean;
setAddress: Dispatch<SetStateAction<string>>;
setUsername: Dispatch<SetStateAction<string>>;
setIsAuth: Dispatch<SetStateAction<boolean>>;
};

Expand Down
5 changes: 4 additions & 1 deletion client/src/pages/connect/AuthForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '@/context';
import {
MILVUS_ADDRESS,
LOGIN_USERNAME,
LAST_TIME_ADDRESS,
MILVUS_URL,
LAST_TIME_DATABASE,
Expand Down Expand Up @@ -63,7 +64,7 @@ export const AuthForm = (props: any) => {
const classes = useStyles();

const { openSnackBar } = useContext(rootContext);
const { setAddress, setIsAuth } = useContext(authContext);
const { setAddress, setUsername, setIsAuth } = useContext(authContext);
const { setDatabase } = useContext(dataContext);

const Logo = icons.zilliz;
Expand Down Expand Up @@ -206,10 +207,12 @@ export const AuthForm = (props: any) => {

setIsAuth(true);
setAddress(form.address);
setUsername(form.username);
setDatabase(result.database);

openSnackBar(successTrans('connect'));
window.localStorage.setItem(MILVUS_ADDRESS, form.address);
window.localStorage.setItem(LOGIN_USERNAME, form.username);
// store address for next time using
window.localStorage.setItem(LAST_TIME_ADDRESS, form.address);
window.localStorage.setItem(LAST_TIME_DATABASE, form.database);
Expand Down

0 comments on commit 5d606f5

Please sign in to comment.