plane/web/core/components/dropdowns/member/index.tsx
Vamsi Krishna 873e4330bc
[WEB-2870]feat: language support (#6215)
* fix: adding language support package

* fix: language support implementation using mobx

* fix: adding more languages for support

* fix: profile settings translations

* feat: added language support for sidebar and user settings

* feat: added language support for deactivation modal

* fix: added project sync after transfer issues (#6200)

* code refactor and improvement (#6203)

* chore: package code refactoring

* chore: component restructuring and refactor

* chore: comment create improvement

* refactor: enhance workspace and project wrapper modularity (#6207)

* [WEB-2678]feat: added functionality to add labels directly from dropdown (#6211)

* enhancement:added functionality to add features directly from dropdown

* fix: fixed import order

* fix: fixed lint errors

* chore: added common component for project activity (#6212)

* chore: added common component for project activity

* fix: added enum

* fix: added enum for initiatives

* - Do not clear temp files that are locked. (#6214)

- Handle edge cases in sync workspace

* fix: labels empty state for drop down (#6216)

* refactor: remove cn helper function from the editor package (#6217)

* * feat: added language support to issue create modal in sidebar
* fix: project activity type

* * fix: added missing translations
* fix: modified translation for plurals

* fix: fixed spanish translation

* dev: language type error in space user profile types

* fix: type fixes

* chore: added alpha tag

---------

Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: Anmol Singh Bhatia <121005188+anmolsinghbhatia@users.noreply.github.com>
Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: Akshita Goyal <36129505+gakshita@users.noreply.github.com>
Co-authored-by: Satish Gandham <satish.iitg@gmail.com>
Co-authored-by: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com>
Co-authored-by: gurusinath <gurusainath007@gmail.com>
2025-01-03 14:16:26 +05:30

182 lines
5.0 KiB
TypeScript

import { useRef, useState } from "react";
import { observer } from "mobx-react";
import { ChevronDown, LucideIcon } from "lucide-react";
import { useTranslation } from "@plane/i18n";
// ui
import { ComboDropDown } from "@plane/ui";
// helpers
import { cn } from "@/helpers/common.helper";
// hooks
import { useMember } from "@/hooks/store";
import { useDropdown } from "@/hooks/use-dropdown";
// components
import { DropdownButton } from "../buttons";
import { BUTTON_VARIANTS_WITH_TEXT } from "../constants";
import { ButtonAvatars } from "./avatar";
// constants
import { MemberOptions } from "./member-options";
// types
import { MemberDropdownProps } from "./types";
type Props = {
projectId?: string;
icon?: LucideIcon;
onClose?: () => void;
renderByDefault?: boolean;
optionsClassName?: string;
} & MemberDropdownProps;
export const MemberDropdown: React.FC<Props> = observer((props) => {
const { t } = useTranslation();
const {
button,
buttonClassName,
buttonContainerClassName,
buttonVariant,
className = "",
disabled = false,
dropdownArrow = false,
dropdownArrowClassName = "",
optionsClassName = "",
hideIcon = false,
multiple,
onChange,
onClose,
placeholder = t("members"),
tooltipContent,
placement,
projectId,
showTooltip = false,
showUserDetails = false,
tabIndex,
value,
icon,
renderByDefault = true,
} = props;
// states
const [isOpen, setIsOpen] = useState(false);
// refs
const dropdownRef = useRef<HTMLDivElement | null>(null);
// popper-js refs
const [referenceElement, setReferenceElement] = useState<HTMLButtonElement | null>(null);
const { getUserDetails } = useMember();
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const comboboxProps: any = {
value,
onChange,
disabled,
};
if (multiple) comboboxProps.multiple = true;
const { handleClose, handleKeyDown, handleOnClick } = useDropdown({
dropdownRef,
isOpen,
onClose,
setIsOpen,
});
const dropdownOnChange = (val: string & string[]) => {
onChange(val);
if (!multiple) handleClose();
};
const getDisplayName = (value: string | string[] | null, showUserDetails: boolean, placeholder: string = "") => {
if (Array.isArray(value)) {
if (value.length > 0) {
if (value.length === 1) {
return getUserDetails(value[0])?.display_name || placeholder;
} else {
return showUserDetails ? `${value.length} ${t("members").toLocaleLowerCase()}` : "";
}
} else {
return placeholder;
}
} else {
if (showUserDetails && value) {
return getUserDetails(value)?.display_name || placeholder;
} else {
return placeholder;
}
}
};
const comboButton = (
<>
{button ? (
<button
ref={setReferenceElement}
type="button"
className={cn("clickable block h-full w-full outline-none", buttonContainerClassName)}
onClick={handleOnClick}
disabled={disabled}
>
{button}
</button>
) : (
<button
ref={setReferenceElement}
type="button"
className={cn(
"clickable block h-full max-w-full outline-none",
{
"cursor-not-allowed text-custom-text-200": disabled,
"cursor-pointer": !disabled,
},
buttonContainerClassName
)}
onClick={handleOnClick}
disabled={disabled}
>
<DropdownButton
className={cn("text-xs", buttonClassName)}
isActive={isOpen}
tooltipHeading={placeholder}
tooltipContent={
tooltipContent ?? `${value?.length ?? 0} ${value?.length !== 1 ? t("assignees") : t("assignee")}`
}
showTooltip={showTooltip}
variant={buttonVariant}
renderToolTipByDefault={renderByDefault}
>
{!hideIcon && <ButtonAvatars showTooltip={showTooltip} userIds={value} icon={icon} />}
{BUTTON_VARIANTS_WITH_TEXT.includes(buttonVariant) && (
<span className="flex-grow truncate leading-5">
{getDisplayName(value, showUserDetails, placeholder)}
</span>
)}
{dropdownArrow && (
<ChevronDown className={cn("h-2.5 w-2.5 flex-shrink-0", dropdownArrowClassName)} aria-hidden="true" />
)}
</DropdownButton>
</button>
)}
</>
);
return (
<ComboDropDown
as="div"
ref={dropdownRef}
tabIndex={tabIndex}
className={cn("h-full", className)}
onChange={dropdownOnChange}
onKeyDown={handleKeyDown}
button={comboButton}
renderByDefault={renderByDefault}
{...comboboxProps}
>
{isOpen && (
<MemberOptions
optionsClassName={optionsClassName}
isOpen={isOpen}
projectId={projectId}
placement={placement}
referenceElement={referenceElement}
/>
)}
</ComboDropDown>
);
});