Skip to content

fix(frontend): resolve the inbox flickering search issue #922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
15 changes: 5 additions & 10 deletions frontend/src/components/inbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/

import { MainContainer, Search, Sidebar } from "@chatscope/chat-ui-kit-react";
import { MainContainer, Sidebar } from "@chatscope/chat-ui-kit-react";
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import { Grid, MenuItem } from "@mui/material";
import { useState } from "react";

import AutoCompleteEntitySelect from "@/app-components/inputs/AutoCompleteEntitySelect";
import { FilterTextfield } from "@/app-components/inputs/FilterTextfield";
import { Input } from "@/app-components/inputs/Input";
import { useSearch } from "@/hooks/useSearch";
import { useTranslate } from "@/hooks/useTranslate";
Expand All @@ -26,7 +27,7 @@ import { AssignedTo } from "./types";

export const Inbox = () => {
const { t } = useTranslate();
const { onSearch, searchPayload, searchText } = useSearch<ISubscriber>({
const { searchPayload, textFieldProps } = useSearch<ISubscriber>({
$or: ["first_name", "last_name"],
});
const [channels, setChannels] = useState<string[]>([]);
Expand All @@ -46,14 +47,8 @@ export const Inbox = () => {
<Grid item width="100%" height="100%" overflow="hidden">
<MainContainer style={{ height: "100%" }}>
<Sidebar position="left">
<Grid paddingX={1} paddingTop={1}>
<Search
value={searchText}
onClearClick={() => onSearch("")}
className="changeColor"
onChange={(v) => onSearch(v)}
placeholder="Search..."
/>
<Grid paddingX={1} pt={2} pb={1} mx={1}>
<FilterTextfield placeholder="Search..." {...textFieldProps} />
</Grid>
<Grid
display="flex"
Expand Down
46 changes: 27 additions & 19 deletions frontend/src/hooks/useSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,34 +57,32 @@ export const useSearch = <T,>(params: TParamItem<T>) => {
const [searchText, setSearchText] = useState<string>(
(router.query.search as string) || "",
);

useEffect(() => {
if (router.query.search !== searchText) {
setSearchText((router.query.search as string) || "");
}
}, [router.query.search]);

const [isActive, setIsActive] = useState(false);
const updateQueryParams = useCallback(
debounce(async (newSearchText: string) => {
await router.replace(
async (newSearchText: string) => {
const { search, ...rest } = { ...router.query, search: newSearchText };

await router.push(
{
pathname: router.pathname,
query: { ...router.query, search: newSearchText || undefined },
query: newSearchText ? { ...rest, search } : rest,
},
undefined,
{ shallow: true },
);
}, 300),
},
[router],
);
const onSearch = (
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string,
) => {
const newSearchText = typeof e === "string" ? e : e.target.value;
const onSearch = debounce(
(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string) => {
setSearchText(typeof e === "string" ? e : e.target.value);
},
300,
);

useEffect(() => {
updateQueryParams(searchText);
}, [searchText]);

setSearchText(newSearchText);
updateQueryParams(newSearchText);
};
const {
$eq: eqInitialParams,
$iLike: iLikeParams,
Expand All @@ -105,5 +103,15 @@ export const useSearch = <T,>(params: TParamItem<T>) => {
}),
},
},
textFieldProps: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the motive behind adding this prop?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main motivation is to group all the fields needed by the Search Text component in one object

value: isActive ? undefined : searchText,
onChange: onSearch,
onMouseOver: () => {
setIsActive(true);
},
onMouseLeave: () => {
setIsActive(false);
},
},
};
};