fix: move debounce to text input and enhance

This commit is contained in:
Mohamed Marrouchi
2025-05-28 17:06:23 +01:00
parent 0c31d3047e
commit 0f8f0dd27f
3 changed files with 66 additions and 18 deletions

View File

@@ -1,31 +1,80 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 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 ClearIcon from "@mui/icons-material/Clear";
import SearchIcon from "@mui/icons-material/Search";
import { TextFieldProps } from "@mui/material";
import {
debounce,
IconButton,
InputAdornment,
TextFieldProps,
} from "@mui/material";
import { useCallback, useMemo, useState } from "react";
import { useTranslate } from "@/hooks/useTranslate";
import { Adornment } from "./Adornment";
import { Input } from "./Input";
export const FilterTextfield = (props: TextFieldProps) => {
const { t } = useTranslate();
export interface FilterTextFieldProps
extends Omit<TextFieldProps, "value" | "onChange"> {
onChange: (value: string) => void;
delay?: number;
clearable: boolean;
defaultValue?: string;
}
export const FilterTextfield = ({
onChange: onSearch,
defaultValue = "",
delay = 500,
clearable = true,
...props
}) => {
const { t } = useTranslate();
const [inputValue, setInputValue] = useState(defaultValue);
const debouncedSearch = useMemo(
() =>
debounce((value: string) => {
onSearch?.(value);
}, delay),
[onSearch, delay],
);
const handleChange = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const value = event.target.value;
setInputValue(value);
debouncedSearch(value);
},
[debouncedSearch],
);
const handleClear = useCallback(() => {
setInputValue("");
debouncedSearch("");
}, [debouncedSearch]);
//TODO: replace the native delete text button by a styled custom button
return (
<Input
type="search"
InputProps={{
startAdornment: <Adornment Icon={SearchIcon} />,
endAdornment: clearable && (
<InputAdornment position="end" onClick={handleClear}>
<IconButton size="small" sx={{ marginRight: -1 }}>
<ClearIcon fontSize="small" />
</IconButton>
</InputAdornment>
),
}}
placeholder={t("placeholder.keywords")}
{...props}
value={inputValue}
onChange={handleChange}
/>
);
};

View File

@@ -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";
@@ -46,13 +47,14 @@ export const Inbox = () => {
<Grid item width="100%" height="100%" overflow="hidden">
<MainContainer style={{ height: "100%" }}>
<Sidebar position="left">
<Grid paddingX={1} paddingTop={1}>
<Search
<Grid paddingX={1} paddingTop={2} paddingBottom={1} mx={1}>
<FilterTextfield onChange={onSearch} defaultValue="" />
{/* <Search
onClearClick={() => onSearch("")}
className="changeColor"
onChange={(v) => onSearch(v)}
placeholder="Search..."
/>
/> */}
</Grid>
<Grid
display="flex"

View File

@@ -6,7 +6,6 @@
* 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 { debounce } from "@mui/material";
import { ChangeEvent, useState } from "react";
import {
@@ -53,12 +52,6 @@ const buildNeqInitialParams = <T,>({
export const useSearch = <T,>(params: TParamItem<T>) => {
const [searchText, setSearchText] = useState<string>("");
const onSearch = debounce(
(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string) => {
setSearchText(typeof e === "string" ? e : e.target.value);
},
300,
);
const {
$eq: eqInitialParams,
$iLike: iLikeParams,
@@ -67,7 +60,11 @@ export const useSearch = <T,>(params: TParamItem<T>) => {
} = params;
return {
onSearch,
onSearch: (
e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement> | string,
) => {
setSearchText(typeof e === "string" ? e : e.target.value);
},
searchPayload: {
where: {
...buildEqInitialParams({ initialParams: eqInitialParams }),