From eae32593cbf0a2d816506e96b3b79b4970d64698 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Thu, 25 Jan 2024 13:29:56 +0530 Subject: [PATCH] chore: added optional tooltip to dropdowns (#3462) --- .../dashboard/widgets/issues-by-priority.tsx | 2 +- .../widgets/issues-by-state-group.tsx | 2 +- web/components/dropdowns/cycle.tsx | 90 +++--- web/components/dropdowns/date.tsx | 134 +++++---- web/components/dropdowns/estimate.tsx | 102 ++++--- web/components/dropdowns/member/buttons.tsx | 117 +++++--- .../dropdowns/member/project-member.tsx | 9 +- .../dropdowns/member/workspace-member.tsx | 9 +- web/components/dropdowns/module.tsx | 90 +++--- web/components/dropdowns/priority.tsx | 263 ++++++++++-------- web/components/dropdowns/project.tsx | 114 +++++--- web/components/dropdowns/state.tsx | 142 +++++++--- web/components/dropdowns/types.d.ts | 1 + .../properties/all-properties.tsx | 6 + .../dashboard/light/overdue-issues.svg | 12 +- 15 files changed, 673 insertions(+), 420 deletions(-) diff --git a/web/components/dashboard/widgets/issues-by-priority.tsx b/web/components/dashboard/widgets/issues-by-priority.tsx index 6b8505044..45b71466d 100644 --- a/web/components/dashboard/widgets/issues-by-priority.tsx +++ b/web/components/dashboard/widgets/issues-by-priority.tsx @@ -128,7 +128,7 @@ export const IssuesByPriorityWidget: React.FC = observer((props) => }; return ( -
+
= observer((props) }; return ( -
+
{ hideIcon = false, hideText = false, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && }{" "} - {!hideText && {cycle?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && }{" "} + {!hideText && {cycle?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -78,18 +82,24 @@ const BackgroundButton = (props: ButtonProps) => { hideIcon = false, hideText = false, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {cycle?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && } + {!hideText && {cycle?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -102,21 +112,24 @@ const TransparentButton = (props: ButtonProps) => { hideIcon = false, hideText = false, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {cycle?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && } + {!hideText && {cycle?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -135,8 +148,9 @@ export const CycleDropdown: React.FC = observer((props) => { placeholder = "Cycle", placement, projectId, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -254,6 +268,7 @@ export const CycleDropdown: React.FC = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : null} diff --git a/web/components/dropdowns/date.tsx b/web/components/dropdowns/date.tsx index e128c6ad3..3cbf3449a 100644 --- a/web/components/dropdowns/date.tsx +++ b/web/components/dropdowns/date.tsx @@ -6,6 +6,8 @@ import { CalendarDays, X } from "lucide-react"; // hooks import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; +// ui +import { Tooltip } from "@plane/ui"; // helpers import { renderFormattedDate } from "helpers/date-time.helper"; import { cn } from "helpers/common.helper"; @@ -33,6 +35,7 @@ type ButtonProps = { hideText?: boolean; onClear: () => void; placeholder: string; + tooltip: boolean; }; const BorderButton = (props: ButtonProps) => { @@ -46,27 +49,34 @@ const BorderButton = (props: ButtonProps) => { hideText = false, onClear, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && icon} - {!hideText && {date ? renderFormattedDate(date) : placeholder}} - {isClearable && ( - { - e.stopPropagation(); - onClear(); - }} - /> - )} -
+
+ {!hideIcon && icon} + {!hideText && {date ? renderFormattedDate(date) : placeholder}} + {isClearable && ( + { + e.stopPropagation(); + onClear(); + }} + /> + )} +
+ ); }; @@ -81,24 +91,34 @@ const BackgroundButton = (props: ButtonProps) => { hideText = false, onClear, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && icon} - {!hideText && {date ? renderFormattedDate(date) : placeholder}} - {isClearable && ( - { - e.stopPropagation(); - onClear(); - }} - /> - )} -
+
+ {!hideIcon && icon} + {!hideText && {date ? renderFormattedDate(date) : placeholder}} + {isClearable && ( + { + e.stopPropagation(); + onClear(); + }} + /> + )} +
+ ); }; @@ -113,27 +133,34 @@ const TransparentButton = (props: ButtonProps) => { hideText = false, onClear, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && icon} - {!hideText && {date ? renderFormattedDate(date) : placeholder}} - {isClearable && ( - { - e.stopPropagation(); - onClear(); - }} - /> - )} -
+
+ {!hideIcon && icon} + {!hideText && {date ? renderFormattedDate(date) : placeholder}} + {isClearable && ( + { + e.stopPropagation(); + onClear(); + }} + /> + )} +
+ ); }; @@ -144,6 +171,7 @@ export const DateDropdown: React.FC = (props) => { buttonVariant, className = "", clearIconClassName = "", + closeOnSelect = true, disabled = false, hideIcon = false, icon = , @@ -153,9 +181,9 @@ export const DateDropdown: React.FC = (props) => { onChange, placeholder = "Date", placement, - value, - closeOnSelect = true, tabIndex, + tooltip = false, + value, } = props; const [isOpen, setIsOpen] = useState(false); // refs @@ -218,6 +246,7 @@ export const DateDropdown: React.FC = (props) => { placeholder={placeholder} isClearable={isClearable && isDateSelected} onClear={() => onChange(null)} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = (props) => { placeholder={placeholder} isClearable={isClearable && isDateSelected} onClear={() => onChange(null)} + tooltip={tooltip} hideText /> ) : buttonVariant === "background-with-text" ? ( @@ -241,6 +271,7 @@ export const DateDropdown: React.FC = (props) => { placeholder={placeholder} isClearable={isClearable && isDateSelected} onClear={() => onChange(null)} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = (props) => { placeholder={placeholder} isClearable={isClearable && isDateSelected} onClear={() => onChange(null)} + tooltip={tooltip} hideText /> ) : buttonVariant === "transparent-with-text" ? ( @@ -264,6 +296,7 @@ export const DateDropdown: React.FC = (props) => { placeholder={placeholder} isClearable={isClearable && isDateSelected} onClear={() => onChange(null)} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = (props) => { placeholder={placeholder} isClearable={isClearable && isDateSelected} onClear={() => onChange(null)} + tooltip={tooltip} hideText /> ) : null} diff --git a/web/components/dropdowns/estimate.tsx b/web/components/dropdowns/estimate.tsx index 5b7a42d71..18144540d 100644 --- a/web/components/dropdowns/estimate.tsx +++ b/web/components/dropdowns/estimate.tsx @@ -8,6 +8,8 @@ import sortBy from "lodash/sortBy"; import { useApplication, useEstimate } from "hooks/store"; import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; +// ui +import { Tooltip } from "@plane/ui"; // helpers import { cn } from "helpers/common.helper"; // types @@ -30,6 +32,7 @@ type ButtonProps = { hideIcon?: boolean; hideText?: boolean; placeholder: string; + tooltip: boolean; }; type DropdownOptions = @@ -49,21 +52,30 @@ const BorderButton = (props: ButtonProps) => { hideIcon = false, hideText = false, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {estimatePoint !== null ? estimatePoint : placeholder}} - {dropdownArrow && ( -
+
+ {!hideIcon && } + {!hideText && ( + {estimatePoint !== null ? estimatePoint : placeholder} + )} + {dropdownArrow && ( +
+ ); }; @@ -76,18 +88,30 @@ const BackgroundButton = (props: ButtonProps) => { hideIcon = false, hideText = false, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {estimatePoint !== null ? estimatePoint : placeholder}} - {dropdownArrow && ( -
+
+ {!hideIcon && } + {!hideText && ( + {estimatePoint !== null ? estimatePoint : placeholder} + )} + {dropdownArrow && ( +
+ ); }; @@ -100,21 +124,30 @@ const TransparentButton = (props: ButtonProps) => { hideIcon = false, hideText = false, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {estimatePoint !== null ? estimatePoint : placeholder}} - {dropdownArrow && ( -
+
+ {!hideIcon && } + {!hideText && ( + {estimatePoint !== null ? estimatePoint : placeholder} + )} + {dropdownArrow && ( +
+ ); }; @@ -133,8 +166,9 @@ export const EstimateDropdown: React.FC = observer((props) => { placeholder = "Estimate", placement, projectId, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -242,6 +276,7 @@ export const EstimateDropdown: React.FC = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : null} diff --git a/web/components/dropdowns/member/buttons.tsx b/web/components/dropdowns/member/buttons.tsx index 3abb9b4cb..c1ec93c53 100644 --- a/web/components/dropdowns/member/buttons.tsx +++ b/web/components/dropdowns/member/buttons.tsx @@ -3,7 +3,7 @@ import { ChevronDown } from "lucide-react"; // hooks import { useMember } from "hooks/store"; // ui -import { Avatar, AvatarGroup, UserGroupIcon } from "@plane/ui"; +import { Avatar, AvatarGroup, Tooltip, UserGroupIcon } from "@plane/ui"; // helpers import { cn } from "helpers/common.helper"; @@ -14,16 +14,17 @@ type ButtonProps = { placeholder: string; hideIcon?: boolean; hideText?: boolean; + tooltip: boolean; userIds: string | string[] | null; }; -const ButtonAvatars = observer(({ userIds }: { userIds: string | string[] | null }) => { +const ButtonAvatars = observer(({ tooltip, userIds }: { tooltip: boolean; userIds: string | string[] | null }) => { const { getUserDetails } = useMember(); if (Array.isArray(userIds)) { if (userIds.length > 0) return ( - + {userIds.map((userId) => { const userDetails = getUserDetails(userId); @@ -35,7 +36,7 @@ const ButtonAvatars = observer(({ userIds }: { userIds: string | string[] | null } else { if (userIds) { const userDetails = getUserDetails(userIds); - return ; + return ; } } @@ -51,6 +52,7 @@ export const BorderButton = observer((props: ButtonProps) => { hideText = false, placeholder, userIds, + tooltip, } = props; // store hooks const { getUserDetails } = useMember(); @@ -58,22 +60,28 @@ export const BorderButton = observer((props: ButtonProps) => { const isMultiple = Array.isArray(userIds); return ( -
- {!hideIcon && } - {!hideText && ( - - {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} - - )} - {dropdownArrow && ( -
+
+ {!hideIcon && } + {!hideText && ( + + {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} + + )} + {dropdownArrow && ( +
+ ); }); @@ -86,6 +94,7 @@ export const BackgroundButton = observer((props: ButtonProps) => { hideText = false, placeholder, userIds, + tooltip, } = props; // store hooks const { getUserDetails } = useMember(); @@ -93,19 +102,28 @@ export const BackgroundButton = observer((props: ButtonProps) => { const isMultiple = Array.isArray(userIds); return ( -
- {!hideIcon && } - {!hideText && ( - - {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} - - )} - {dropdownArrow && ( -
+
+ {!hideIcon && } + {!hideText && ( + + {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} + + )} + {dropdownArrow && ( +
+ ); }); @@ -118,6 +136,7 @@ export const TransparentButton = observer((props: ButtonProps) => { hideText = false, placeholder, userIds, + tooltip, } = props; // store hooks const { getUserDetails } = useMember(); @@ -125,21 +144,27 @@ export const TransparentButton = observer((props: ButtonProps) => { const isMultiple = Array.isArray(userIds); return ( -
- {!hideIcon && } - {!hideText && ( - - {userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder} - - )} - {dropdownArrow && ( -
+
+ {!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 8393c32f0..7cd878841 100644 --- a/web/components/dropdowns/member/project-member.tsx +++ b/web/components/dropdowns/member/project-member.tsx @@ -36,8 +36,9 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { placeholder = "Members", placement, projectId, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -146,6 +147,7 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} hideText /> ) : buttonVariant === "background-with-text" ? ( @@ -165,6 +168,7 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} hideText /> ) : buttonVariant === "transparent-with-text" ? ( @@ -184,6 +189,7 @@ export const ProjectMemberDropdown: React.FC = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} hideText /> ) : null} diff --git a/web/components/dropdowns/member/workspace-member.tsx b/web/components/dropdowns/member/workspace-member.tsx index 55806c51e..aaa1d7f7e 100644 --- a/web/components/dropdowns/member/workspace-member.tsx +++ b/web/components/dropdowns/member/workspace-member.tsx @@ -31,8 +31,9 @@ export const WorkspaceMemberDropdown: React.FC = observer(( onChange, placeholder = "Members", placement, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -133,6 +134,7 @@ export const WorkspaceMemberDropdown: React.FC = observer(( dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = observer(( dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} hideText /> ) : buttonVariant === "background-with-text" ? ( @@ -152,6 +155,7 @@ export const WorkspaceMemberDropdown: React.FC = observer(( dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = observer(( dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} hideText /> ) : buttonVariant === "transparent-with-text" ? ( @@ -171,6 +176,7 @@ export const WorkspaceMemberDropdown: React.FC = observer(( dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = observer(( dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} hideText /> ) : null} diff --git a/web/components/dropdowns/module.tsx b/web/components/dropdowns/module.tsx index 3420dfca1..e41555802 100644 --- a/web/components/dropdowns/module.tsx +++ b/web/components/dropdowns/module.tsx @@ -8,7 +8,7 @@ import { useApplication, useModule } from "hooks/store"; import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; // icons -import { DiceIcon } from "@plane/ui"; +import { DiceIcon, Tooltip } from "@plane/ui"; // helpers import { cn } from "helpers/common.helper"; // types @@ -40,6 +40,7 @@ type ButtonProps = { hideText?: boolean; module: IModule | null; placeholder: string; + tooltip: boolean; }; const BorderButton = (props: ButtonProps) => { @@ -51,21 +52,24 @@ const BorderButton = (props: ButtonProps) => { hideText = false, module, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {module?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && } + {!hideText && {module?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -78,18 +82,24 @@ const BackgroundButton = (props: ButtonProps) => { hideText = false, module, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {module?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && } + {!hideText && {module?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -102,21 +112,24 @@ const TransparentButton = (props: ButtonProps) => { hideText = false, module, placeholder, + tooltip, } = props; return ( -
- {!hideIcon && } - {!hideText && {module?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && } + {!hideText && {module?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -135,8 +148,9 @@ export const ModuleDropdown: React.FC = observer((props) => { placeholder = "Module", placement, projectId, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -253,6 +267,7 @@ export const ModuleDropdown: React.FC = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : null} diff --git a/web/components/dropdowns/priority.tsx b/web/components/dropdowns/priority.tsx index fc87559c3..dff1f5aaa 100644 --- a/web/components/dropdowns/priority.tsx +++ b/web/components/dropdowns/priority.tsx @@ -2,11 +2,12 @@ import { Fragment, ReactNode, useRef, useState } from "react"; import { Combobox } from "@headlessui/react"; import { usePopper } from "react-popper"; import { Check, ChevronDown, Search } from "lucide-react"; +import { useTheme } from "next-themes"; // hooks import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; // icons -import { PriorityIcon } from "@plane/ui"; +import { PriorityIcon, Tooltip } from "@plane/ui"; // helpers import { cn } from "helpers/common.helper"; // types @@ -14,7 +15,6 @@ import { TIssuePriorities } from "@plane/types"; import { TDropdownProps } from "./types"; // constants import { ISSUE_PRIORITIES } from "constants/issue"; -import { useTheme } from "next-themes"; type Props = TDropdownProps & { button?: ReactNode; @@ -33,6 +33,7 @@ type ButtonProps = { hideText?: boolean; highlightUrgent: boolean; priority: TIssuePriorities; + tooltip: boolean; }; const BorderButton = (props: ButtonProps) => { @@ -44,6 +45,7 @@ const BorderButton = (props: ButtonProps) => { hideText = false, highlightUrgent, priority, + tooltip, } = props; const priorityDetails = ISSUE_PRIORITIES.find((p) => p.key === priority); @@ -57,47 +59,49 @@ const BorderButton = (props: ButtonProps) => { }; return ( - + ); }; @@ -110,6 +114,7 @@ const BackgroundButton = (props: ButtonProps) => { hideText = false, highlightUrgent, priority, + tooltip, } = props; const priorityDetails = ISSUE_PRIORITIES.find((p) => p.key === priority); @@ -123,47 +128,49 @@ const BackgroundButton = (props: ButtonProps) => { }; return ( - + ); }; @@ -176,6 +183,7 @@ const TransparentButton = (props: ButtonProps) => { hideText = false, highlightUrgent, priority, + tooltip, } = props; const priorityDetails = ISSUE_PRIORITIES.find((p) => p.key === priority); @@ -189,47 +197,49 @@ const TransparentButton = (props: ButtonProps) => { }; return ( - + ); }; @@ -247,8 +257,9 @@ export const PriorityDropdown: React.FC = (props) => { highlightUrgent = true, onChange, placement, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -341,6 +352,7 @@ export const PriorityDropdown: React.FC = (props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = (props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} hideText /> ) : buttonVariant === "background-with-text" ? ( @@ -364,6 +377,7 @@ export const PriorityDropdown: React.FC = (props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = (props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} hideText /> ) : buttonVariant === "transparent-with-text" ? ( @@ -387,6 +402,7 @@ export const PriorityDropdown: React.FC = (props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = (props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} hideText /> ) : null} diff --git a/web/components/dropdowns/project.tsx b/web/components/dropdowns/project.tsx index bbaf3d43f..cdbe21b08 100644 --- a/web/components/dropdowns/project.tsx +++ b/web/components/dropdowns/project.tsx @@ -7,6 +7,8 @@ import { Check, ChevronDown, Search } from "lucide-react"; import { useProject } from "hooks/store"; import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; +// ui +import { Tooltip } from "@plane/ui"; // helpers import { cn } from "helpers/common.helper"; import { renderEmoji } from "helpers/emoji.helper"; @@ -30,6 +32,7 @@ type ButtonProps = { hideText?: boolean; placeholder: string; project: IProject | null; + tooltip: boolean; }; const BorderButton = (props: ButtonProps) => { @@ -41,25 +44,28 @@ const BorderButton = (props: ButtonProps) => { hideText = false, placeholder, project, + tooltip, } = props; return ( -
- {!hideIcon && ( - - {project?.emoji ? renderEmoji(project?.emoji) : project?.icon_prop ? renderEmoji(project?.icon_prop) : null} - - )} - {!hideText && {project?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && ( + + {project?.emoji ? renderEmoji(project?.emoji) : project?.icon_prop ? renderEmoji(project?.icon_prop) : null} + + )} + {!hideText && {project?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -72,22 +78,28 @@ const BackgroundButton = (props: ButtonProps) => { hideText = false, placeholder, project, + tooltip, } = props; return ( -
- {!hideIcon && ( - - {project?.emoji ? renderEmoji(project?.emoji) : project?.icon_prop ? renderEmoji(project?.icon_prop) : null} - - )} - {!hideText && {project?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && ( + + {project?.emoji ? renderEmoji(project?.emoji) : project?.icon_prop ? renderEmoji(project?.icon_prop) : null} + + )} + {!hideText && {project?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -100,25 +112,28 @@ const TransparentButton = (props: ButtonProps) => { hideText = false, placeholder, project, + tooltip, } = props; return ( -
- {!hideIcon && ( - - {project?.emoji ? renderEmoji(project?.emoji) : project?.icon_prop ? renderEmoji(project?.icon_prop) : null} - - )} - {!hideText && {project?.name ?? placeholder}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && ( + + {project?.emoji ? renderEmoji(project?.emoji) : project?.icon_prop ? renderEmoji(project?.icon_prop) : null} + + )} + {!hideText && {project?.name ?? placeholder}} + {dropdownArrow && ( +
+
); }; @@ -136,8 +151,9 @@ export const ProjectDropdown: React.FC = observer((props) => { onChange, placeholder = "Project", placement, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -239,6 +255,7 @@ export const ProjectDropdown: React.FC = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-with-text" ? ( = observer((props) => { dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} placeholder={placeholder} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = observer((props) => { hideIcon={hideIcon} hideText placeholder={placeholder} + tooltip={tooltip} /> ) : null} diff --git a/web/components/dropdowns/state.tsx b/web/components/dropdowns/state.tsx index 37ae8ad72..fb8446d23 100644 --- a/web/components/dropdowns/state.tsx +++ b/web/components/dropdowns/state.tsx @@ -8,7 +8,7 @@ import { useApplication, useProjectState } from "hooks/store"; import { useDropdownKeyDown } from "hooks/use-dropdown-key-down"; import useOutsideClickDetector from "hooks/use-outside-click-detector"; // icons -import { StateGroupIcon } from "@plane/ui"; +import { StateGroupIcon, Tooltip } from "@plane/ui"; // helpers import { cn } from "helpers/common.helper"; // types @@ -31,65 +31,111 @@ type ButtonProps = { hideIcon?: boolean; hideText?: boolean; state: IState | undefined; + tooltip: boolean; }; const BorderButton = (props: ButtonProps) => { - const { className, dropdownArrow, dropdownArrowClassName, hideIcon = false, hideText = false, state } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + state, + tooltip, + } = props; return ( -
- {!hideIcon && ( - - )} - {!hideText && {state?.name ?? "State"}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && ( + + )} + {!hideText && {state?.name ?? "State"}} + {dropdownArrow && ( +
+
); }; const BackgroundButton = (props: ButtonProps) => { - const { className, dropdownArrow, dropdownArrowClassName, hideIcon = false, hideText = false, state } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + state, + tooltip, + } = props; return ( -
- {!hideIcon && ( - - )} - {!hideText && {state?.name ?? "State"}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && ( + + )} + {!hideText && {state?.name ?? "State"}} + {dropdownArrow && ( +
+
); }; const TransparentButton = (props: ButtonProps) => { - const { className, dropdownArrow, dropdownArrowClassName, hideIcon = false, hideText = false, state } = props; + const { + className, + dropdownArrow, + dropdownArrowClassName, + hideIcon = false, + hideText = false, + state, + tooltip, + } = props; return ( -
- {!hideIcon && ( - - )} - {!hideText && {state?.name ?? "State"}} - {dropdownArrow && ( -
+ +
+ {!hideIcon && ( + + )} + {!hideText && {state?.name ?? "State"}} + {dropdownArrow && ( +
+
); }; @@ -107,8 +153,9 @@ export const StateDropdown: React.FC = observer((props) => { onChange, placement, projectId, - value, tabIndex, + tooltip = false, + value, } = props; // states const [query, setQuery] = useState(""); @@ -204,6 +251,7 @@ export const StateDropdown: React.FC = observer((props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} /> ) : buttonVariant === "border-without-text" ? ( = observer((props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} hideText /> ) : buttonVariant === "background-with-text" ? ( @@ -221,6 +270,7 @@ export const StateDropdown: React.FC = observer((props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} /> ) : buttonVariant === "background-without-text" ? ( = observer((props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} hideText /> ) : buttonVariant === "transparent-with-text" ? ( @@ -238,6 +289,7 @@ export const StateDropdown: React.FC = observer((props) => { dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} hideIcon={hideIcon} + tooltip={tooltip} /> ) : buttonVariant === "transparent-without-text" ? ( = observer((props) => { className={buttonClassName} dropdownArrow={dropdownArrow && !disabled} dropdownArrowClassName={dropdownArrowClassName} + hideIcon={hideIcon} + tooltip={tooltip} hideText /> ) : null} diff --git a/web/components/dropdowns/types.d.ts b/web/components/dropdowns/types.d.ts index 5bf3080ea..f9a078382 100644 --- a/web/components/dropdowns/types.d.ts +++ b/web/components/dropdowns/types.d.ts @@ -18,4 +18,5 @@ export type TDropdownProps = { placeholder?: string; placement?: Placement; tabIndex?: number; + tooltip?: boolean; }; diff --git a/web/components/issues/issue-layouts/properties/all-properties.tsx b/web/components/issues/issue-layouts/properties/all-properties.tsx index 6dde75703..b7e1fae4f 100644 --- a/web/components/issues/issue-layouts/properties/all-properties.tsx +++ b/web/components/issues/issue-layouts/properties/all-properties.tsx @@ -81,6 +81,7 @@ export const IssueProperties: React.FC = observer((props) => { projectId={issue.project_id} disabled={isReadOnly} buttonVariant="border-with-text" + tooltip />
@@ -94,6 +95,7 @@ export const IssueProperties: React.FC = observer((props) => { disabled={isReadOnly} buttonVariant="border-without-text" buttonClassName="border" + tooltip />
@@ -121,6 +123,7 @@ export const IssueProperties: React.FC = observer((props) => { placeholder="Start date" buttonVariant={issue.start_date ? "border-with-text" : "border-without-text"} disabled={isReadOnly} + tooltip />
@@ -136,6 +139,7 @@ export const IssueProperties: React.FC = observer((props) => { placeholder="Due date" buttonVariant={issue.target_date ? "border-with-text" : "border-without-text"} disabled={isReadOnly} + tooltip />
@@ -151,6 +155,7 @@ export const IssueProperties: React.FC = observer((props) => { multiple buttonVariant={issue.assignee_ids?.length > 0 ? "transparent-without-text" : "border-without-text"} buttonClassName={issue.assignee_ids?.length > 0 ? "hover:bg-transparent px-0" : ""} + tooltip />
@@ -165,6 +170,7 @@ export const IssueProperties: React.FC = observer((props) => { projectId={issue.project_id} disabled={isReadOnly} buttonVariant="border-with-text" + tooltip />
diff --git a/web/public/empty-state/dashboard/light/overdue-issues.svg b/web/public/empty-state/dashboard/light/overdue-issues.svg index 504c76498..1c66ddd0b 100644 --- a/web/public/empty-state/dashboard/light/overdue-issues.svg +++ b/web/public/empty-state/dashboard/light/overdue-issues.svg @@ -1,9 +1,9 @@ - - - - - - + + + + + +