All files / src/features/ChangeLog/filter-components UserFilter.tsx

78.57% Statements 22/28
61.53% Branches 8/13
66.66% Functions 8/12
83.33% Lines 20/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96                            117x         22x 22x     22x     22x   22x 1x     22x       22x         22x 1x   1x     1x 1x   1x     22x     5x     1x     22x                                       1x                          
import { useState } from "react";
import { SelectorOption } from "@common/TableFilters/SelectorOption";
import ContextualMenu from "@shared/ContextualMenu/ContextualMenu";
import FilterItem from "./FilterItem";
import useListUsers from "../hooks/useListUsers";
import GiveAvatar from "@shared/Avatar/GiveAvatar";
import { useCustomThemeV2 } from "@theme/hooks/useCustomThemeV2";
 
interface IUserFilterProps {
  merchantId: number;
  selectedUsers: SelectorOption[];
  onApply: (users: SelectorOption[]) => void;
}
 
const UserFilter = ({
  merchantId,
  selectedUsers = [],
  onApply,
}: IUserFilterProps) => {
  const { isMobileView } = useCustomThemeV2();
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
 
  const { data, isLoading, handleSearch, handleScroll, searchValue } =
    useListUsers({ merchantId, enabled: Boolean(anchorEl) });
 
  const title =
    selectedUsers.length > 0 ? `User (${selectedUsers.length})` : "User";
 
  const handleOpen = (e: React.MouseEvent<HTMLElement>) => {
    setAnchorEl(e.currentTarget);
  };
 
  const handleClose = () => {
    setAnchorEl(null);
  };
 
  const handleReset = (e: React.MouseEvent) => {
    e.stopPropagation();
    onApply([]);
  };
 
  const handleToggleUser = (userId: number | string) => {
    const exists = selectedUsers.find((u) => u.id === userId);
    let newSelection;
    Iif (exists) {
      newSelection = selectedUsers.filter((u) => u.id !== userId);
    } else {
      const option = data.find((d) => d.id === userId);
      newSelection = option ? [...selectedUsers, option] : selectedUsers;
    }
    onApply(newSelection);
  };
 
  const options = data.map((user) => ({
    text: user.label,
    id: user.id,
    showCheckedIcon: selectedUsers.some((s) => s.id === user.id),
    checkedIconType: "Check" as const,
    Image: <GiveAvatar imageUrl={user.imageURL} size="24px" />,
    onClick: () => handleToggleUser(user.id),
  }));
 
  return (
    <>
      <FilterItem
        isSelected={selectedUsers.length > 0}
        onCancel={handleReset}
        title={title}
        onClick={handleOpen}
        isOpen={Boolean(anchorEl)}
      />
      {/* High z-index to ensure menu appears above GiveDraggableModal */}
      <ContextualMenu
        anchorEl={anchorEl}
        handleClose={handleClose}
        color={isMobileView ? "primary" : "tertiary"}
        texture={isMobileView ? "solid" : "blurred"}
        options={options}
        isMultiSelect
        isLoading={isLoading}
        menuWidth={280}
        searchBarProps={{
          handleChange: (val) => handleSearch(val),
          value: searchValue || "",
          placeholder: "Search",
        }}
        horizontalOrigin="left"
        onEndReached={handleScroll as any}
        drawerZIndex={1000000}
      />
    </>
  );
};
 
export default UserFilter;