* [#420] passed a new param to people search to customize slotprops * Added back function lost in rebase --------- Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
@@ -7,7 +7,13 @@ import ListItem from "@mui/material/ListItem";
|
|||||||
import ListItemAvatar from "@mui/material/ListItemAvatar";
|
import ListItemAvatar from "@mui/material/ListItemAvatar";
|
||||||
import ListItemText from "@mui/material/ListItemText";
|
import ListItemText from "@mui/material/ListItemText";
|
||||||
import TextField from "@mui/material/TextField";
|
import TextField from "@mui/material/TextField";
|
||||||
import { type ReactNode, useCallback, useEffect, useState } from "react";
|
import {
|
||||||
|
type ReactNode,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
HTMLAttributes,
|
||||||
|
} from "react";
|
||||||
import { searchUsers } from "../../features/User/userAPI";
|
import { searchUsers } from "../../features/User/userAPI";
|
||||||
import PeopleOutlineOutlinedIcon from "@mui/icons-material/PeopleOutlineOutlined";
|
import PeopleOutlineOutlinedIcon from "@mui/icons-material/PeopleOutlineOutlined";
|
||||||
import Chip from "@mui/material/Chip";
|
import Chip from "@mui/material/Chip";
|
||||||
@@ -15,6 +21,7 @@ import { useTheme } from "@mui/material/styles";
|
|||||||
import { getAccessiblePair } from "../Calendar/utils/calendarColorsUtils";
|
import { getAccessiblePair } from "../Calendar/utils/calendarColorsUtils";
|
||||||
import { useI18n } from "twake-i18n";
|
import { useI18n } from "twake-i18n";
|
||||||
import { SnackbarAlert } from "../Loading/SnackBarAlert";
|
import { SnackbarAlert } from "../Loading/SnackBarAlert";
|
||||||
|
import { PopperProps, PaperProps } from "@mui/material";
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
email: string;
|
email: string;
|
||||||
@@ -42,6 +49,7 @@ export function PeopleSearch({
|
|||||||
placeholder,
|
placeholder,
|
||||||
inputSlot,
|
inputSlot,
|
||||||
customRenderInput,
|
customRenderInput,
|
||||||
|
customSlotProps,
|
||||||
}: {
|
}: {
|
||||||
selectedUsers: User[];
|
selectedUsers: User[];
|
||||||
onChange: (event: any, users: User[]) => void;
|
onChange: (event: any, users: User[]) => void;
|
||||||
@@ -58,6 +66,11 @@ export function PeopleSearch({
|
|||||||
query: string,
|
query: string,
|
||||||
setQuery: (value: string) => void
|
setQuery: (value: string) => void
|
||||||
) => ReactNode;
|
) => ReactNode;
|
||||||
|
customSlotProps?: {
|
||||||
|
popper?: Partial<PopperProps>;
|
||||||
|
paper?: Partial<PaperProps>;
|
||||||
|
listbox?: Partial<HTMLAttributes<HTMLUListElement>>;
|
||||||
|
};
|
||||||
}) {
|
}) {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const [query, setQuery] = useState("");
|
const [query, setQuery] = useState("");
|
||||||
@@ -119,53 +132,87 @@ export function PeopleSearch({
|
|||||||
}, [objectTypes, query, t]);
|
}, [objectTypes, query, t]);
|
||||||
|
|
||||||
const defaultRenderInput = useCallback(
|
const defaultRenderInput = useCallback(
|
||||||
(params: AutocompleteRenderInputParams) => (
|
(params: AutocompleteRenderInputParams) => {
|
||||||
<>
|
const inputProps = {
|
||||||
<label htmlFor={params.id} className="visually-hidden">
|
...params.InputProps,
|
||||||
{t("peopleSearch.label")}
|
startAdornment: (
|
||||||
</label>
|
<>
|
||||||
<TextField
|
<PeopleOutlineOutlinedIcon sx={{ mr: 1, color: "action.active" }} />
|
||||||
{...params}
|
{params.InputProps.startAdornment}
|
||||||
error={!!inputError}
|
</>
|
||||||
helperText={inputError}
|
),
|
||||||
placeholder={searchPlaceholder}
|
endAdornment: (
|
||||||
label=""
|
<>
|
||||||
inputProps={{
|
{loading ? <CircularProgress color="inherit" size={20} /> : null}
|
||||||
...params.inputProps,
|
{params.InputProps.endAdornment}
|
||||||
autoComplete: "off",
|
</>
|
||||||
}}
|
),
|
||||||
onKeyDown={(e) => {
|
};
|
||||||
if (e.key === "Enter" && onToggleEventPreview) {
|
|
||||||
e.preventDefault();
|
const enhancedParamsWithInputProps = {
|
||||||
onToggleEventPreview();
|
...params,
|
||||||
}
|
InputProps: inputProps,
|
||||||
}}
|
inputProps: {
|
||||||
slotProps={{
|
...params.inputProps,
|
||||||
input: {
|
autoComplete: "off",
|
||||||
...params.InputProps,
|
},
|
||||||
autoComplete: "off",
|
};
|
||||||
startAdornment: (
|
|
||||||
<>
|
const { InputProps, ...enhancedParams } = enhancedParamsWithInputProps;
|
||||||
<PeopleOutlineOutlinedIcon
|
|
||||||
style={{ marginRight: 8, color: "rgba(0, 0, 0, 0.54)" }}
|
const handleEnterKey = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||||
/>
|
if (e.key === "Enter" && onToggleEventPreview) {
|
||||||
{params.InputProps.startAdornment}
|
e.preventDefault();
|
||||||
</>
|
onToggleEventPreview();
|
||||||
),
|
}
|
||||||
endAdornment: (
|
};
|
||||||
<>
|
|
||||||
{loading ? (
|
const defaultTextFieldProps = {
|
||||||
<CircularProgress color="inherit" size={20} />
|
error: !!inputError,
|
||||||
) : null}
|
helperText: inputError,
|
||||||
{params.InputProps.endAdornment}
|
placeholder: searchPlaceholder,
|
||||||
</>
|
label: "",
|
||||||
),
|
onKeyDown: handleEnterKey,
|
||||||
},
|
slotProps: {
|
||||||
}}
|
input: {
|
||||||
/>
|
...inputProps,
|
||||||
</>
|
},
|
||||||
),
|
},
|
||||||
[inputError, t, onToggleEventPreview, loading]
|
};
|
||||||
|
|
||||||
|
if (inputSlot) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<label htmlFor={params.id} className="visually-hidden">
|
||||||
|
{t("peopleSearch.label")}
|
||||||
|
</label>
|
||||||
|
{inputSlot({
|
||||||
|
...enhancedParamsWithInputProps,
|
||||||
|
error: !!inputError,
|
||||||
|
helperText: inputError,
|
||||||
|
placeholder: searchPlaceholder,
|
||||||
|
label: "",
|
||||||
|
onKeyDown: handleEnterKey,
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<label htmlFor={params.id} className="visually-hidden">
|
||||||
|
{t("peopleSearch.label")}
|
||||||
|
</label>
|
||||||
|
<TextField
|
||||||
|
{...enhancedParams}
|
||||||
|
{...defaultTextFieldProps}
|
||||||
|
InputProps={inputProps}
|
||||||
|
size="medium"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[inputError, t, onToggleEventPreview, loading, searchPlaceholder]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -225,6 +272,7 @@ export function PeopleSearch({
|
|||||||
);
|
);
|
||||||
onChange(event, mapped);
|
onChange(event, mapped);
|
||||||
}}
|
}}
|
||||||
|
slotProps={customSlotProps}
|
||||||
renderInput={(params) =>
|
renderInput={(params) =>
|
||||||
customRenderInput
|
customRenderInput
|
||||||
? customRenderInput(params, query, setQuery)
|
? customRenderInput(params, query, setQuery)
|
||||||
|
|||||||
@@ -233,6 +233,26 @@ export default function SearchBar() {
|
|||||||
}}
|
}}
|
||||||
objectTypes={["user", "contact"]}
|
objectTypes={["user", "contact"]}
|
||||||
onToggleEventPreview={() => {}}
|
onToggleEventPreview={() => {}}
|
||||||
|
customSlotProps={{
|
||||||
|
popper: {
|
||||||
|
anchorEl: containerRef.current,
|
||||||
|
placement: "bottom-start",
|
||||||
|
sx: {
|
||||||
|
minWidth: searchWidth,
|
||||||
|
"& .MuiPaper-root": {
|
||||||
|
width: "100%",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
modifiers: [
|
||||||
|
{
|
||||||
|
name: "offset",
|
||||||
|
options: {
|
||||||
|
offset: [0, 8],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}}
|
||||||
customRenderInput={(
|
customRenderInput={(
|
||||||
params: AutocompleteRenderInputParams,
|
params: AutocompleteRenderInputParams,
|
||||||
query: string,
|
query: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user