diff --git a/packages/ui/src/dropdowns/custom-search-select.tsx b/packages/ui/src/dropdowns/custom-search-select.tsx index 44b91bb299..d1778e31aa 100644 --- a/packages/ui/src/dropdowns/custom-search-select.tsx +++ b/packages/ui/src/dropdowns/custom-search-select.tsx @@ -118,7 +118,7 @@ export const CustomSearchSelect = (props: ICustomSearchSelectProps) => {
= ({ - isOpen, - handleClose: onClose, - searchParams, - handleOnSubmit, - workspaceLevelToggle = false, -}) => { +export const ExistingIssuesListModal: React.FC = (props) => { + const { isOpen, handleClose: onClose, searchParams, handleOnSubmit, workspaceLevelToggle = false } = props; + // states const [searchTerm, setSearchTerm] = useState(""); const [issues, setIssues] = useState([]); const [isSearching, setIsSearching] = useState(false); @@ -92,7 +88,7 @@ export const ExistingIssuesListModal: React.FC = ({ return ( <> setSearchTerm("")} appear> - + {}}> = ({ )} - {selectedIssues.length > 0 && ( -
- +
+ + {selectedIssues.length > 0 && ( -
- )} + )} +
diff --git a/web/components/dropdowns/cycle.tsx b/web/components/dropdowns/cycle.tsx index cf3bd1cfc8..5645132c4d 100644 --- a/web/components/dropdowns/cycle.tsx +++ b/web/components/dropdowns/cycle.tsx @@ -18,6 +18,7 @@ import { TDropdownProps } from "./types"; type Props = TDropdownProps & { button?: ReactNode; dropdownArrow?: boolean; + dropdownArrowClassName?: string; onChange: (val: string | null) => void; projectId: string; value: string | null; @@ -26,8 +27,11 @@ type Props = TDropdownProps & { type ButtonProps = { className?: string; cycle: ICycle | null; + hideIcon: boolean; hideText?: boolean; dropdownArrow: boolean; + dropdownArrowClassName: string; + placeholder: string; }; type DropdownOptions = @@ -39,7 +43,15 @@ type DropdownOptions = | undefined; const BorderButton = (props: ButtonProps) => { - const { className, cycle, dropdownArrow, hideText = false } = props; + const { + className, + cycle, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + } = props; return (
{ className )} > - - {!hideText && {cycle?.name ?? "Cycle"}} - {dropdownArrow &&
); }; const BackgroundButton = (props: ButtonProps) => { - const { className, cycle, dropdownArrow, hideText = false } = props; + const { + className, + cycle, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + } = props; return (
- - {!hideText && {cycle?.name ?? "Cycle"}} - {dropdownArrow &&
); }; const TransparentButton = (props: ButtonProps) => { - const { className, cycle, dropdownArrow, hideText = false } = props; + const { + className, + cycle, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + } = props; return (
{ className )} > - - {!hideText && {cycle?.name ?? "Cycle"}} - {dropdownArrow &&
); }; @@ -95,7 +129,10 @@ export const CycleDropdown: React.FC = observer((props) => { className = "", disabled = false, dropdownArrow = false, + dropdownArrowClassName = "", + hideIcon = false, onChange, + placeholder = "Cycle", placement, projectId, value, @@ -178,9 +215,7 @@ export const CycleDropdown: React.FC = observer((props) => { as="div" ref={dropdownRef} tabIndex={tabIndex} - className={cn("h-full flex-shrink-0", { - className, - })} + className={cn("h-full", className)} value={value} onChange={onChange} disabled={disabled} @@ -210,44 +245,63 @@ export const CycleDropdown: React.FC = observer((props) => { )} onClick={openDropdown} > + {/* TODO: move button components to a single file for each dropdown */} {buttonVariant === "border-with-text" ? ( ) : buttonVariant === "border-without-text" ? ( ) : buttonVariant === "background-with-text" ? ( ) : buttonVariant === "background-without-text" ? ( ) : buttonVariant === "transparent-with-text" ? ( ) : buttonVariant === "transparent-without-text" ? ( ) : null} diff --git a/web/components/dropdowns/date.tsx b/web/components/dropdowns/date.tsx index 6e6785284b..e128c6ad39 100644 --- a/web/components/dropdowns/date.tsx +++ b/web/components/dropdowns/date.tsx @@ -13,28 +13,40 @@ import { cn } from "helpers/common.helper"; import { TDropdownProps } from "./types"; type Props = TDropdownProps & { + clearIconClassName?: string; icon?: React.ReactNode; isClearable?: boolean; minDate?: Date; maxDate?: Date; onChange: (val: Date | null) => void; - placeholder: string; value: Date | string | null; closeOnSelect?: boolean; }; type ButtonProps = { className?: string; + clearIconClassName: string; date: string | Date | null; icon: React.ReactNode; isClearable: boolean; + hideIcon?: boolean; hideText?: boolean; onClear: () => void; placeholder: string; }; const BorderButton = (props: ButtonProps) => { - const { className, date, icon, isClearable, hideText = false, onClear, placeholder } = props; + const { + className, + clearIconClassName, + date, + icon, + isClearable, + hideIcon = false, + hideText = false, + onClear, + placeholder, + } = props; return (
{ className )} > - {icon} + {!hideIcon && icon} {!hideText && {date ? renderFormattedDate(date) : placeholder}} {isClearable && ( { e.stopPropagation(); onClear(); @@ -59,17 +71,27 @@ const BorderButton = (props: ButtonProps) => { }; const BackgroundButton = (props: ButtonProps) => { - const { className, date, icon, isClearable, hideText = false, onClear, placeholder } = props; + const { + className, + clearIconClassName, + date, + icon, + isClearable, + hideIcon = false, + hideText = false, + onClear, + placeholder, + } = props; return (
- {icon} + {!hideIcon && icon} {!hideText && {date ? renderFormattedDate(date) : placeholder}} {isClearable && ( { e.stopPropagation(); onClear(); @@ -81,7 +103,17 @@ const BackgroundButton = (props: ButtonProps) => { }; const TransparentButton = (props: ButtonProps) => { - const { className, date, icon, isClearable, hideText = false, onClear, placeholder } = props; + const { + className, + clearIconClassName, + date, + icon, + isClearable, + hideIcon = false, + hideText = false, + onClear, + placeholder, + } = props; return (
{ className )} > - {icon} + {!hideIcon && icon} {!hideText && {date ? renderFormattedDate(date) : placeholder}} {isClearable && ( { e.stopPropagation(); onClear(); @@ -111,13 +143,15 @@ export const DateDropdown: React.FC = (props) => { buttonContainerClassName, buttonVariant, className = "", + clearIconClassName = "", disabled = false, + hideIcon = false, icon = , isClearable = true, minDate, maxDate, onChange, - placeholder, + placeholder = "Date", placement, value, closeOnSelect = true, @@ -157,7 +191,7 @@ export const DateDropdown: React.FC = (props) => { as="div" ref={dropdownRef} tabIndex={tabIndex} - className={cn("h-full flex-shrink-0", className)} + className={cn("h-full", className)} onKeyDown={handleKeyDown} > @@ -178,6 +212,8 @@ export const DateDropdown: React.FC = (props) => { = (props) => { = (props) => { = (props) => { = (props) => { = (props) => { void; projectId: string; value: number | null; @@ -25,7 +26,10 @@ type ButtonProps = { className?: string; estimatePoint: string | null; dropdownArrow: boolean; + dropdownArrowClassName: string; + hideIcon?: boolean; hideText?: boolean; + placeholder: string; }; type DropdownOptions = @@ -37,7 +41,15 @@ type DropdownOptions = | undefined; const BorderButton = (props: ButtonProps) => { - const { className, estimatePoint, dropdownArrow, hideText = false } = props; + const { + className, + estimatePoint, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + } = props; return (
{ className )} > - - {!hideText && {estimatePoint !== null ? estimatePoint : "Estimate"}} - {dropdownArrow &&
); }; const BackgroundButton = (props: ButtonProps) => { - const { className, estimatePoint, dropdownArrow, hideText = false } = props; + const { + className, + estimatePoint, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + } = props; return (
- - {!hideText && {estimatePoint !== null ? estimatePoint : "Estimate"}} - {dropdownArrow &&
); }; const TransparentButton = (props: ButtonProps) => { - const { className, estimatePoint, dropdownArrow, hideText = false } = props; + const { + className, + estimatePoint, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + } = props; return (
{ className )} > - - {!hideText && {estimatePoint !== null ? estimatePoint : "Estimate"}} - {dropdownArrow &&
); }; @@ -93,7 +127,10 @@ export const EstimateDropdown: React.FC = observer((props) => { className = "", disabled = false, dropdownArrow = false, + dropdownArrowClassName = "", + hideIcon = false, onChange, + placeholder = "Estimate", placement, projectId, value, @@ -167,9 +204,7 @@ export const EstimateDropdown: React.FC = observer((props) => { as="div" ref={dropdownRef} tabIndex={tabIndex} - className={cn("h-full flex-shrink-0", { - className, - })} + className={cn("h-full w-full", className)} value={value} onChange={onChange} disabled={disabled} @@ -204,39 +239,57 @@ export const EstimateDropdown: React.FC = observer((props) => { estimatePoint={selectedEstimate} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} + placeholder={placeholder} /> ) : buttonVariant === "border-without-text" ? ( ) : buttonVariant === "background-with-text" ? ( ) : buttonVariant === "background-without-text" ? ( ) : buttonVariant === "transparent-with-text" ? ( ) : buttonVariant === "transparent-without-text" ? ( ) : null} diff --git a/web/components/dropdowns/member/buttons.tsx b/web/components/dropdowns/member/buttons.tsx index 53003473d9..3abb9b4cbc 100644 --- a/web/components/dropdowns/member/buttons.tsx +++ b/web/components/dropdowns/member/buttons.tsx @@ -10,7 +10,9 @@ import { cn } from "helpers/common.helper"; type ButtonProps = { className?: string; dropdownArrow: boolean; + dropdownArrowClassName: string; placeholder: string; + hideIcon?: boolean; hideText?: boolean; userIds: string | string[] | null; }; @@ -41,7 +43,15 @@ const ButtonAvatars = observer(({ userIds }: { userIds: string | string[] | null }); export const BorderButton = observer((props: ButtonProps) => { - const { className, dropdownArrow, hideText = false, placeholder, userIds } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + userIds, + } = props; // store hooks const { getUserDetails } = useMember(); @@ -54,19 +64,29 @@ export const BorderButton = observer((props: ButtonProps) => { className )} > - + {!hideIcon && } {!hideText && ( {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} )} - {dropdownArrow &&
); }); export const BackgroundButton = observer((props: ButtonProps) => { - const { className, dropdownArrow, hideText = false, placeholder, userIds } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + userIds, + } = props; // store hooks const { getUserDetails } = useMember(); @@ -76,19 +96,29 @@ export const BackgroundButton = observer((props: ButtonProps) => {
- + {!hideIcon && } {!hideText && ( {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} )} - {dropdownArrow &&
); }); export const TransparentButton = observer((props: ButtonProps) => { - const { className, dropdownArrow, hideText = false, placeholder, userIds } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + placeholder, + userIds, + } = props; // store hooks const { getUserDetails } = useMember(); @@ -101,13 +131,15 @@ export const TransparentButton = observer((props: ButtonProps) => { className )} > - + {!hideIcon && } {!hideText && ( {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} )} - {dropdownArrow &&
); }); diff --git a/web/components/dropdowns/member/project-member.tsx b/web/components/dropdowns/member/project-member.tsx index 0c733272dc..8393c32f0e 100644 --- a/web/components/dropdowns/member/project-member.tsx +++ b/web/components/dropdowns/member/project-member.tsx @@ -1,4 +1,4 @@ -import { Fragment, useEffect, useRef, useState } from "react"; +import { Fragment, useRef, useState } from "react"; import { observer } from "mobx-react-lite"; import { Combobox } from "@headlessui/react"; import { usePopper } from "react-popper"; @@ -29,6 +29,8 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { className = "", disabled = false, dropdownArrow = false, + dropdownArrowClassName = "", + hideIcon = false, multiple, onChange, placeholder = "Members", @@ -108,9 +110,7 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { as="div" ref={dropdownRef} tabIndex={tabIndex} - className={cn("h-full flex-shrink-0", { - className, - })} + className={cn("h-full", className)} onKeyDown={handleKeyDown} {...comboboxProps} > @@ -143,6 +143,8 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} /> ) : buttonVariant === "border-without-text" ? ( @@ -150,6 +152,8 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} hideText /> @@ -158,6 +162,8 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} /> ) : buttonVariant === "background-without-text" ? ( @@ -165,6 +171,8 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} hideText /> @@ -173,6 +181,8 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} /> ) : buttonVariant === "transparent-without-text" ? ( @@ -180,6 +190,8 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} hideText /> diff --git a/web/components/dropdowns/member/types.d.ts b/web/components/dropdowns/member/types.d.ts index fbf52c969d..673bea8aa2 100644 --- a/web/components/dropdowns/member/types.d.ts +++ b/web/components/dropdowns/member/types.d.ts @@ -3,6 +3,7 @@ import { TDropdownProps } from "../types"; export type MemberDropdownProps = TDropdownProps & { button?: ReactNode; dropdownArrow?: boolean; + dropdownArrowClassName?: string; placeholder?: string; } & ( | { diff --git a/web/components/dropdowns/member/workspace-member.tsx b/web/components/dropdowns/member/workspace-member.tsx index 4089e52b9f..55806c51e1 100644 --- a/web/components/dropdowns/member/workspace-member.tsx +++ b/web/components/dropdowns/member/workspace-member.tsx @@ -5,6 +5,8 @@ import { usePopper } from "react-popper"; import { Check, Search } from "lucide-react"; // hooks import { useMember, useUser } from "hooks/store"; +import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; +import useOutsideClickDetector from "hooks/use-outside-click-detector"; // components import { BackgroundButton, BorderButton, TransparentButton } from "components/dropdowns"; // icons @@ -13,8 +15,6 @@ import { Avatar } from "@plane/ui"; import { cn } from "helpers/common.helper"; // types import { MemberDropdownProps } from "./types"; -import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; -import useOutsideClickDetector from "hooks/use-outside-click-detector"; export const WorkspaceMemberDropdown: React.FC = observer((props) => { const { @@ -25,6 +25,8 @@ export const WorkspaceMemberDropdown: React.FC = observer(( className = "", disabled = false, dropdownArrow = false, + dropdownArrowClassName = "", + hideIcon = false, multiple, onChange, placeholder = "Members", @@ -97,9 +99,7 @@ export const WorkspaceMemberDropdown: React.FC = observer(( as="div" ref={dropdownRef} tabIndex={tabIndex} - className={cn("h-full flex-shrink-0", { - className, - })} + className={cn("h-full", className)} {...comboboxProps} handleKeyDown={handleKeyDown} > @@ -130,6 +130,8 @@ export const WorkspaceMemberDropdown: React.FC = observer(( userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} /> ) : buttonVariant === "border-without-text" ? ( @@ -137,6 +139,8 @@ export const WorkspaceMemberDropdown: React.FC = observer(( userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} hideText /> @@ -145,6 +149,8 @@ export const WorkspaceMemberDropdown: React.FC = observer(( userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} /> ) : buttonVariant === "background-without-text" ? ( @@ -152,6 +158,8 @@ export const WorkspaceMemberDropdown: React.FC = observer(( userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} hideText /> @@ -160,6 +168,8 @@ export const WorkspaceMemberDropdown: React.FC = observer(( userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} /> ) : buttonVariant === "transparent-without-text" ? ( @@ -167,6 +177,8 @@ export const WorkspaceMemberDropdown: React.FC = observer(( userIds={value} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} placeholder={placeholder} hideText /> diff --git a/web/components/dropdowns/module.tsx b/web/components/dropdowns/module.tsx index 9bce79460a..3420dfca10 100644 --- a/web/components/dropdowns/module.tsx +++ b/web/components/dropdowns/module.tsx @@ -18,6 +18,7 @@ import { TDropdownProps } from "./types"; type Props = TDropdownProps & { button?: ReactNode; dropdownArrow?: boolean; + dropdownArrowClassName?: string; onChange: (val: string | null) => void; projectId: string; value: string | null; @@ -34,12 +35,23 @@ type DropdownOptions = type ButtonProps = { className?: string; dropdownArrow: boolean; + dropdownArrowClassName: string; + hideIcon?: boolean; hideText?: boolean; module: IModule | null; + placeholder: string; }; const BorderButton = (props: ButtonProps) => { - const { className, dropdownArrow, hideText = false, module } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + module, + placeholder, + } = props; return (
{ className )} > - - {!hideText && {module?.name ?? "Module"}} - {dropdownArrow &&
); }; const BackgroundButton = (props: ButtonProps) => { - const { className, dropdownArrow, hideText = false, module } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + module, + placeholder, + } = props; return (
- - {!hideText && {module?.name ?? "Module"}} - {dropdownArrow &&
); }; const TransparentButton = (props: ButtonProps) => { - const { className, dropdownArrow, hideText = false, module } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + module, + placeholder, + } = props; return (
{ className )} > - - {!hideText && {module?.name ?? "Module"}} - {dropdownArrow &&
); }; @@ -95,7 +129,10 @@ export const ModuleDropdown: React.FC = observer((props) => { className = "", disabled = false, dropdownArrow = false, + dropdownArrowClassName = "", + hideIcon = false, onChange, + placeholder = "Module", placement, projectId, value, @@ -178,7 +215,7 @@ export const ModuleDropdown: React.FC = observer((props) => { as="div" ref={dropdownRef} tabIndex={tabIndex} - className={cn("h-full flex-shrink-0", className)} + className={cn("h-full", className)} value={value} onChange={onChange} disabled={disabled} @@ -213,39 +250,57 @@ export const ModuleDropdown: React.FC = observer((props) => { module={selectedModule} className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} + dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} + placeholder={placeholder} /> ) : buttonVariant === "border-without-text" ? ( ) : buttonVariant === "background-with-text" ? ( ) : buttonVariant === "background-without-text" ? ( ) : buttonVariant === "transparent-with-text" ? ( ) : buttonVariant === "transparent-without-text" ? ( ) : null} diff --git a/web/components/dropdowns/priority.tsx b/web/components/dropdowns/priority.tsx index afcfaa8e49..fc87559c35 100644 --- a/web/components/dropdowns/priority.tsx +++ b/web/components/dropdowns/priority.tsx @@ -19,6 +19,7 @@ import { useTheme } from "next-themes"; type Props = TDropdownProps & { button?: ReactNode; dropdownArrow?: boolean; + dropdownArrowClassName?: string; highlightUrgent?: boolean; onChange: (val: TIssuePriorities) => void; value: TIssuePriorities; @@ -27,13 +28,23 @@ type Props = TDropdownProps & { type ButtonProps = { className?: string; dropdownArrow: boolean; + dropdownArrowClassName: string; + hideIcon?: boolean; hideText?: boolean; highlightUrgent: boolean; priority: TIssuePriorities; }; const BorderButton = (props: ButtonProps) => { - const { className, dropdownArrow, hideText = false, highlightUrgent, priority } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + highlightUrgent, + priority, + } = props; const priorityDetails = ISSUE_PRIORITIES.find((p) => p.key === priority); @@ -59,35 +70,47 @@ const BorderButton = (props: ButtonProps) => { className )} > -
-
+ > +
+ )} {!hideText && {priorityDetails?.title}} - {dropdownArrow &&