Ver código fonte

change get search from url method

tumao 4 anos atrás
pai
commit
e09a6d6812

+ 41 - 27
client/src/components/customInput/SearchInput.tsx

@@ -1,8 +1,7 @@
 import { InputAdornment, makeStyles, TextField } from '@material-ui/core';
 import { useRef, FC, useState, useEffect, useMemo } from 'react';
 import { useTranslation } from 'react-i18next';
-import { useHistory, useLocation } from 'react-router-dom';
-import { parseLocationSearch } from '../../utils/Format';
+import { useHistory } from 'react-router-dom';
 import Icons from '../icons/Icons';
 import { SearchType } from './Types';
 
@@ -57,6 +56,8 @@ const useSearchStyles = makeStyles(theme => ({
     color: '#aeaebb',
     cursor: 'pointer',
     fontSize: '20px',
+    width: (props: { searched: boolean }) => `${props.searched ? 0 : '20px'}`,
+
     transition: 'width 0.2s',
   },
   clearIcon: {
@@ -78,15 +79,21 @@ let timer: NodeJS.Timeout | null = null;
 
 const SearchInput: FC<SearchType> = props => {
   const { searchText = '', onClear = () => {}, onSearch = () => {} } = props;
-  const [searchValue, setSearchValue] = useState<string>(searchText);
+  const [searchValue, setSearchValue] = useState<string | null>(
+    searchText || null
+  );
 
-  const searched = useMemo(() => searchValue !== '', [searchValue]);
+  const [isInit, setIsInit] = useState<boolean>(true);
+
+  const searched = useMemo(
+    () => searchValue !== '' && searchValue !== null,
+    [searchValue]
+  );
 
   const classes = useSearchStyles({ searched });
   const { t: commonTrans } = useTranslation();
 
   const history = useHistory();
-  const location = useLocation();
 
   const inputRef = useRef<any>(null);
 
@@ -96,31 +103,36 @@ const SearchInput: FC<SearchType> = props => {
   }, [onSearch]);
 
   useEffect(() => {
-    const { search } = parseLocationSearch(location.search);
-    if (search) {
-      setSearchValue(search);
+    if (timer) {
+      clearTimeout(timer);
     }
-  }, [location.search]);
-
-  useEffect(() => {
-    timer = setTimeout(() => {
-      const location = history.location;
-      const params = new URLSearchParams(location.search);
-      if (searchValue) {
-        params.append('search', searchValue);
-      } else {
+    if (searchValue !== null && !isInit) {
+      timer = setTimeout(() => {
+        // save other params data and remove last time search info
+        const location = history.location;
+        const params = new URLSearchParams(location.search);
         params.delete('search');
-      }
-      // add search value in url
-      history.push({ search: params.toString() });
 
-      savedSearchFn.current(searchValue);
-    }, 300);
+        if (searchValue) {
+          params.append('search', searchValue);
+        }
+        // add search value in url
+        history.push({ search: params.toString() });
+
+        savedSearchFn.current(searchValue);
+      }, 300);
+    }
 
     return () => {
       timer && clearTimeout(timer);
     };
-  }, [searchValue, history]);
+  }, [searchValue, history, isInit]);
+
+  const handleSearch = (value: string | null) => {
+    if (value !== null) {
+      onSearch(value);
+    }
+  };
 
   return (
     <div className={classes.wrapper}>
@@ -137,6 +149,7 @@ const SearchInput: FC<SearchType> = props => {
                 className={`flex-center ${classes.iconWrapper}`}
                 onClick={e => {
                   setSearchValue('');
+                  setIsInit(false);
                   inputRef.current.focus();
                   onClear();
                 }}
@@ -149,7 +162,7 @@ const SearchInput: FC<SearchType> = props => {
             <InputAdornment position="start">
               <span
                 className={classes.searchWrapper}
-                onClick={() => onSearch(searchValue)}
+                onClick={() => handleSearch(searchValue)}
               >
                 {Icons.search({ classes: { root: classes.searchIcon } })}
               </span>
@@ -157,8 +170,9 @@ const SearchInput: FC<SearchType> = props => {
           ),
         }}
         onChange={e => {
-          const value = e.target.value;
+          const value = e.target.value.trim();
           setSearchValue(value);
+          setIsInit(false);
           if (value === '') {
             onClear();
           }
@@ -166,11 +180,11 @@ const SearchInput: FC<SearchType> = props => {
         onKeyPress={e => {
           if (e.key === 'Enter') {
             // Do code here
-            onSearch(searchValue);
+            handleSearch(searchValue);
             e.preventDefault();
           }
         }}
-        value={searchValue}
+        value={searchValue || ''}
         placeholder={commonTrans('search')}
       />
     </div>

+ 17 - 3
client/src/pages/collections/Collections.tsx

@@ -21,6 +21,7 @@ import DeleteTemplate from '../../components/customDialog/DeleteDialogTemplate';
 import { CollectionHttp } from '../../http/Collection';
 import { useDialogHook } from '../../hooks/Dialog';
 import Highlighter from 'react-highlight-words';
+import { parseLocationSearch } from '../../utils/Format';
 
 const useStyles = makeStyles((theme: Theme) => ({
   emptyWrapper: {
@@ -46,6 +47,8 @@ const useStyles = makeStyles((theme: Theme) => ({
 }));
 
 let timer: NodeJS.Timeout | null = null;
+// get init search value from url
+const { search = '' } = parseLocationSearch(window.location.search);
 
 const Collections = () => {
   useNavigationHook(ALL_ROUTER_TYPES.COLLECTIONS);
@@ -85,12 +88,17 @@ const Collections = () => {
       const res = await CollectionHttp.getCollections();
       const statusRes = await CollectionHttp.getCollectionsIndexState();
       setLoading(false);
+
       const collections = 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}
+              <Highlighter
+                textToHighlight={v._name}
+                searchWords={[search]}
+                highlightClassName={classes.highlight}
+              />
             </Link>
           ),
           statusElement: <Status status={v._status} />,
@@ -104,12 +112,17 @@ const Collections = () => {
         return v;
       });
 
+      // filter collection if url contains search param
+      const filteredCollections = collections.filter(collection =>
+        collection._name.includes(search)
+      );
+
       setCollections(collections);
-      setSearchedCollections(collections);
+      setSearchedCollections(filteredCollections);
     } catch (err) {
       setLoading(false);
     }
-  }, [classes.link]);
+  }, [classes.link, classes.highlight]);
 
   useEffect(() => {
     fetchData();
@@ -238,6 +251,7 @@ const Collections = () => {
     {
       label: 'Search',
       icon: 'search',
+      searchText: search,
       onSearch: (value: string) => {
         handleSearch(value);
       },

+ 32 - 17
client/src/pages/partitions/partitions.tsx

@@ -20,6 +20,7 @@ import { ManageRequestMethods } from '../../types/Common';
 // import { useDialogHook } from '../../hooks/Dialog';
 import DeleteTemplate from '../../components/customDialog/DeleteDialogTemplate';
 import Highlighter from 'react-highlight-words';
+import { parseLocationSearch } from '../../utils/Format';
 
 const useStyles = makeStyles((theme: Theme) => ({
   wrapper: {
@@ -36,6 +37,8 @@ const useStyles = makeStyles((theme: Theme) => ({
 }));
 
 let timer: NodeJS.Timeout | null = null;
+// get init search value from url
+const { search = '' } = parseLocationSearch(window.location.search);
 
 const Partitions: FC<{
   collectionName: string;
@@ -69,23 +72,35 @@ const Partitions: FC<{
   const { setDialog, handleCloseDialog, openSnackBar } =
     useContext(rootContext);
 
-  const fetchPartitions = useCallback(async (collectionName: string) => {
-    try {
-      const res = await PartitionHttp.getPartitions(collectionName);
+  const fetchPartitions = useCallback(
+    async (collectionName: string) => {
+      try {
+        const res = await PartitionHttp.getPartitions(collectionName);
 
-      const partitions: PartitionView[] = res.map(p =>
-        Object.assign(p, {
-          _nameElement: <>{p._formatName}</>,
-          _statusElement: <Status status={p._status} />,
-        })
-      );
-      setLoading(false);
-      setPartitions(partitions);
-      setSearchedPartitions(partitions);
-    } catch (err) {
-      setLoading(false);
-    }
-  }, []);
+        const partitions: PartitionView[] = res.map(p =>
+          Object.assign(p, {
+            _nameElement: (
+              <Highlighter
+                textToHighlight={p._formatName}
+                searchWords={[search]}
+                highlightClassName={classes.highlight}
+              />
+            ),
+            _statusElement: <Status status={p._status} />,
+          })
+        );
+        const filteredPartitions = partitions.filter(p =>
+          p._formatName.includes(search)
+        );
+        setLoading(false);
+        setPartitions(partitions);
+        setSearchedPartitions(filteredPartitions);
+      } catch (err) {
+        setLoading(false);
+      }
+    },
+    [classes.highlight]
+  );
 
   useEffect(() => {
     fetchPartitions(collectionName);
@@ -152,7 +167,6 @@ const Partitions: FC<{
         });
         return c;
       });
-
       setLoading(false);
       setSearchedPartitions(highlightList);
     }, 300);
@@ -208,6 +222,7 @@ const Partitions: FC<{
     {
       label: 'Search',
       icon: 'search',
+      searchText: search,
       onSearch: (value: string) => {
         handleSearch(value);
       },