Browse Source

Fix back button not working (#448)

* history try

Signed-off-by: ryjiang <jiangruiyi@gmail.com>

* stash

Signed-off-by: ryjiang <jiangruiyi@gmail.com>

* fix back issue casued by the list filter

Signed-off-by: ruiyi.jiang <ruiyi.jiang@zilliz.com>

* fix back button

Signed-off-by: ruiyi.jiang <ruiyi.jiang@zilliz.com>

* stash

Signed-off-by: ruiyi.jiang <ruiyi.jiang@zilliz.com>

* fix back

Signed-off-by: ryjiang <jiangruiyi@gmail.com>

---------

Signed-off-by: ryjiang <jiangruiyi@gmail.com>
Signed-off-by: ruiyi.jiang <ruiyi.jiang@zilliz.com>
ryjiang 1 year ago
parent
commit
fcb7ce885e

+ 14 - 4
client/src/components/customInput/SearchInput.tsx

@@ -1,7 +1,6 @@
 import { InputAdornment, makeStyles, TextField } from '@material-ui/core';
 import { InputAdornment, makeStyles, TextField } from '@material-ui/core';
 import { useRef, FC, useState, useEffect, useMemo } from 'react';
 import { useRef, FC, useState, useEffect, useMemo } from 'react';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
-import { useSearchParams } from 'react-router-dom';
 import Icons from '../icons/Icons';
 import Icons from '../icons/Icons';
 import { SearchType } from './Types';
 import { SearchType } from './Types';
 
 
@@ -76,7 +75,6 @@ const useSearchStyles = makeStyles(theme => ({
 
 
 const SearchInput: FC<SearchType> = props => {
 const SearchInput: FC<SearchType> = props => {
   const { searchText = '', onClear = () => {}, onSearch = () => {} } = props;
   const { searchText = '', onClear = () => {}, onSearch = () => {} } = props;
-  const [searchParams, setSearchParams] = useSearchParams();
   const [searchValue, setSearchValue] = useState<string>(searchText || '');
   const [searchValue, setSearchValue] = useState<string>(searchText || '');
   const searched = useMemo(() => searchValue !== '', [searchValue]);
   const searched = useMemo(() => searchValue !== '', [searchValue]);
   const classes = useSearchStyles({ searched });
   const classes = useSearchStyles({ searched });
@@ -88,8 +86,20 @@ const SearchInput: FC<SearchType> = props => {
   };
   };
 
 
   useEffect(() => {
   useEffect(() => {
-    searchParams[searchValue ? 'set' : 'delete']('search', searchValue);
-    setSearchParams(searchParams);
+    let hashPart = window.location.hash.substring(1);
+    // remove search part from hash part, include the '?'
+    hashPart = hashPart.replace(/(\?search=)[^&]+(&?)/, '$2');
+
+    let searchPart = !searchValue
+      ? ''
+      : `?search=${encodeURIComponent(searchValue)}`;
+
+    hashPart = `${hashPart}${searchPart}`;
+
+    const newUrl = `${window.location.pathname}#${hashPart}`;
+
+    window.history.replaceState(null, '', newUrl);
+
     handleSearch(searchValue);
     handleSearch(searchValue);
   }, [searchValue]);
   }, [searchValue]);
 
 

+ 3 - 5
client/src/components/customTabList/RouteTabList.tsx

@@ -63,18 +63,16 @@ const a11yProps = (index: number) => {
 const RouteTabList: FC<ITabListProps> = props => {
 const RouteTabList: FC<ITabListProps> = props => {
   const { tabs, activeIndex = 0, wrapperClass = '' } = props;
   const { tabs, activeIndex = 0, wrapperClass = '' } = props;
   const classes = useStyles();
   const classes = useStyles();
-  const [value, setValue] = useState<number>(activeIndex);
   const navigate = useNavigate();
   const navigate = useNavigate();
   const location = useLocation();
   const location = useLocation();
 
 
   const handleChange = (event: any, newValue: any) => {
   const handleChange = (event: any, newValue: any) => {
-    setValue(newValue);
     const newPath =
     const newPath =
       location.pathname.split('/').slice(0, -1).join('/') +
       location.pathname.split('/').slice(0, -1).join('/') +
       '/' +
       '/' +
       tabs[newValue].path;
       tabs[newValue].path;
 
 
-    navigate(`${newPath}`);
+    navigate(newPath);
   };
   };
 
 
   return (
   return (
@@ -86,7 +84,7 @@ const RouteTabList: FC<ITabListProps> = props => {
         }}
         }}
         // if not provide this property, Material will add single span element by default
         // if not provide this property, Material will add single span element by default
         TabIndicatorProps={{ children: <div className="tab-indicator" /> }}
         TabIndicatorProps={{ children: <div className="tab-indicator" /> }}
-        value={value}
+        value={activeIndex}
         onChange={handleChange}
         onChange={handleChange}
         aria-label="tabs"
         aria-label="tabs"
       >
       >
@@ -104,7 +102,7 @@ const RouteTabList: FC<ITabListProps> = props => {
       {tabs.map((tab, index) => (
       {tabs.map((tab, index) => (
         <TabPanel
         <TabPanel
           key={tab.label}
           key={tab.label}
-          value={value}
+          value={activeIndex}
           index={index}
           index={index}
           className={classes.tabPanel}
           className={classes.tabPanel}
         >
         >

+ 6 - 16
client/src/pages/databases/collections/partitions/Partitions.tsx

@@ -6,7 +6,7 @@ import AttuGrid from '@/components/grid/Grid';
 import { ColDefinitionsType, ToolBarConfig } from '@/components/grid/Types';
 import { ColDefinitionsType, ToolBarConfig } from '@/components/grid/Types';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import { usePaginationHook, useInsertDialogHook } from '@/hooks';
 import { usePaginationHook, useInsertDialogHook } from '@/hooks';
-import icons from '@/components/icons/Icons';
+import Icons from '@/components/icons/Icons';
 import CustomToolTip from '@/components/customToolTip/CustomToolTip';
 import CustomToolTip from '@/components/customToolTip/CustomToolTip';
 import { rootContext } from '@/context';
 import { rootContext } from '@/context';
 import { CollectionService, PartitionService } from '@/http';
 import { CollectionService, PartitionService } from '@/http';
@@ -43,7 +43,6 @@ const Partitions = () => {
   const [search, setSearch] = useState<string>(
   const [search, setSearch] = useState<string>(
     (searchParams.get('search') as string) || ''
     (searchParams.get('search') as string) || ''
   );
   );
-  const QuestionIcon = icons.question;
 
 
   const { handleInsertDialog } = useInsertDialogHook();
   const { handleInsertDialog } = useInsertDialogHook();
 
 
@@ -51,10 +50,6 @@ const Partitions = () => {
     []
     []
   );
   );
   const [partitions, setPartitions] = useState<PartitionData[]>([]);
   const [partitions, setPartitions] = useState<PartitionData[]>([]);
-  const [searchedPartitions, setSearchedPartitions] = useState<PartitionData[]>(
-    []
-  );
-
   const [loading, setLoading] = useState<boolean>(true);
   const [loading, setLoading] = useState<boolean>(true);
   const { setDialog, openSnackBar } = useContext(rootContext);
   const { setDialog, openSnackBar } = useContext(rootContext);
 
 
@@ -77,14 +72,9 @@ const Partitions = () => {
     fetchPartitions(collectionName);
     fetchPartitions(collectionName);
   }, [collectionName]);
   }, [collectionName]);
 
 
-  // search
-  useEffect(() => {
-    const list = search
-      ? partitions.filter(p => p.name.includes(search))
-      : partitions;
-
-    setSearchedPartitions(list);
-  }, [search, partitions]);
+  const list = search
+    ? partitions.filter(p => p.name.includes(search))
+    : partitions;
 
 
   const {
   const {
     pageSize,
     pageSize,
@@ -96,7 +86,7 @@ const Partitions = () => {
     order,
     order,
     orderBy,
     orderBy,
     handleGridSort,
     handleGridSort,
-  } = usePaginationHook(searchedPartitions);
+  } = usePaginationHook(list);
 
 
   // on delete
   // on delete
   const onDelete = () => {
   const onDelete = () => {
@@ -232,7 +222,7 @@ const Partitions = () => {
         <span className="flex-center with-max-content">
         <span className="flex-center with-max-content">
           {t('rowCount')}
           {t('rowCount')}
           <CustomToolTip title={t('tooltip')}>
           <CustomToolTip title={t('tooltip')}>
-            <QuestionIcon classes={{ root: classes.icon }} />
+            <Icons.question classes={{ root: classes.icon }} />
           </CustomToolTip>
           </CustomToolTip>
         </span>
         </span>
       ),
       ),

+ 7 - 3
client/src/pages/home/DatabaseCard.tsx

@@ -1,6 +1,6 @@
 import { FC, useContext } from 'react';
 import { FC, useContext } from 'react';
 import { makeStyles, Theme, Typography, useTheme } from '@material-ui/core';
 import { makeStyles, Theme, Typography, useTheme } from '@material-ui/core';
-import { useNavigate } from 'react-router-dom';
+import { useNavigate, useLocation } from 'react-router-dom';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import { MilvusService } from '@/http';
 import { MilvusService } from '@/http';
 import icons from '@/components/icons/Icons';
 import icons from '@/components/icons/Icons';
@@ -98,7 +98,9 @@ const DatabaseCard: FC<DatabaseCardProps> = ({
   const { t: btnTrans } = useTranslation('btn');
   const { t: btnTrans } = useTranslation('btn');
   const { t: dialogTrans } = useTranslation('dialog');
   const { t: dialogTrans } = useTranslation('dialog');
 
 
-  const navigation = useNavigate();
+  const navigate = useNavigate();
+  const location = useLocation();
+
   const classes = useStyles();
   const classes = useStyles();
   const theme = useTheme();
   const theme = useTheme();
   const DbIcon = icons.database;
   const DbIcon = icons.database;
@@ -113,7 +115,9 @@ const DatabaseCard: FC<DatabaseCardProps> = ({
     setDatabase(database.name);
     setDatabase(database.name);
 
 
     // navigate to database detail page
     // navigate to database detail page
-    navigation(`/databases/${database.name}`);
+    const targetPath = `/databases/${database.name}`;
+
+    navigate(targetPath);
   };
   };
 
 
   const handleDelete = async () => {
   const handleDelete = async () => {

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

@@ -16,8 +16,6 @@ const RouterComponent = () => {
     <Router>
     <Router>
       <Routes>
       <Routes>
         <Route path="/" element={<Index />}>
         <Route path="/" element={<Index />}>
-          <Route index element={<Databases />} />
-
           <Route path="databases" element={<Databases />} />
           <Route path="databases" element={<Databases />} />
           <Route path="databases/:databaseName" element={<Databases />} />
           <Route path="databases/:databaseName" element={<Databases />} />
           <Route
           <Route