From cc5001217cb038ba1d5bd8d487be2fdc858e3213 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal Date: Wed, 24 Jan 2024 13:26:37 +0530 Subject: [PATCH 1/5] style: peek overview and issue details properties --- .../ui/src/dropdowns/custom-search-select.tsx | 2 +- .../modals/existing-issues-list-modal.tsx | 26 +- web/components/dropdowns/cycle.tsx | 83 ++- web/components/dropdowns/date.tsx | 75 ++- web/components/dropdowns/estimate.tsx | 85 ++- web/components/dropdowns/member/buttons.tsx | 50 +- .../dropdowns/member/project-member.tsx | 20 +- web/components/dropdowns/member/types.d.ts | 1 + .../dropdowns/member/workspace-member.tsx | 22 +- web/components/dropdowns/module.tsx | 81 ++- web/components/dropdowns/priority.tsx | 189 ++++--- web/components/dropdowns/project.tsx | 99 +++- web/components/dropdowns/state.tsx | 51 +- web/components/dropdowns/types.d.ts | 2 + .../issues/issue-detail/cycle-select.tsx | 93 +--- .../issues/issue-detail/module-select.tsx | 73 ++- .../issues/issue-detail/parent-select.tsx | 153 +++--- .../issues/issue-detail/relation-select.tsx | 177 +++--- .../issues/issue-detail/sidebar.tsx | 504 +++++++++--------- .../properties/all-properties.tsx | 9 +- .../issues/peek-overview/properties.tsx | 429 +++++++++------ .../issues/view-select/estimate.tsx | 1 - web/store/issue/issue-details/root.store.ts | 13 +- 23 files changed, 1365 insertions(+), 873 deletions(-) diff --git a/packages/ui/src/dropdowns/custom-search-select.tsx b/packages/ui/src/dropdowns/custom-search-select.tsx index 9695eb9319..b312a41ed4 100644 --- a/packages/ui/src/dropdowns/custom-search-select.tsx +++ b/packages/ui/src/dropdowns/custom-search-select.tsx @@ -114,7 +114,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..23cb77a89b 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} @@ -215,39 +250,57 @@ export const CycleDropdown: React.FC = observer((props) => { cycle={selectedCycle} 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/date.tsx b/web/components/dropdowns/date.tsx index b346529dc4..e9f0472788 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, @@ -153,12 +187,7 @@ export const DateDropdown: React.FC = (props) => { useOutsideClickDetector(dropdownRef, closeDropdown); return ( - + 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 &&