mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: issue sidebar and peek overview improvement (#3488)
* chore: issue peek overview and sidebar properties focused state improvement * fix: added name of the issue in issue relation * chore: issue sidebar and peek overview properties improvement * chore: issue assignee improvement for sidebar and peek overview --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
This commit is contained in:
parent
09a1a55da8
commit
483fc57601
@ -304,6 +304,7 @@ class IssueRelationSerializer(BaseSerializer):
|
|||||||
sequence_id = serializers.IntegerField(
|
sequence_id = serializers.IntegerField(
|
||||||
source="related_issue.sequence_id", read_only=True
|
source="related_issue.sequence_id", read_only=True
|
||||||
)
|
)
|
||||||
|
name = serializers.CharField(source="related_issue.name", read_only=True)
|
||||||
relation_type = serializers.CharField(read_only=True)
|
relation_type = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -313,6 +314,7 @@ class IssueRelationSerializer(BaseSerializer):
|
|||||||
"project_id",
|
"project_id",
|
||||||
"sequence_id",
|
"sequence_id",
|
||||||
"relation_type",
|
"relation_type",
|
||||||
|
"name",
|
||||||
]
|
]
|
||||||
read_only_fields = [
|
read_only_fields = [
|
||||||
"workspace",
|
"workspace",
|
||||||
@ -328,6 +330,7 @@ class RelatedIssueSerializer(BaseSerializer):
|
|||||||
sequence_id = serializers.IntegerField(
|
sequence_id = serializers.IntegerField(
|
||||||
source="issue.sequence_id", read_only=True
|
source="issue.sequence_id", read_only=True
|
||||||
)
|
)
|
||||||
|
name = serializers.CharField(source="issue.name", read_only=True)
|
||||||
relation_type = serializers.CharField(read_only=True)
|
relation_type = serializers.CharField(read_only=True)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -337,6 +340,7 @@ class RelatedIssueSerializer(BaseSerializer):
|
|||||||
"project_id",
|
"project_id",
|
||||||
"sequence_id",
|
"sequence_id",
|
||||||
"relation_type",
|
"relation_type",
|
||||||
|
"name",
|
||||||
]
|
]
|
||||||
read_only_fields = [
|
read_only_fields = [
|
||||||
"workspace",
|
"workspace",
|
||||||
|
@ -30,6 +30,7 @@ type ButtonProps = {
|
|||||||
hideIcon: boolean;
|
hideIcon: boolean;
|
||||||
hideText?: boolean;
|
hideText?: boolean;
|
||||||
dropdownArrow: boolean;
|
dropdownArrow: boolean;
|
||||||
|
isActive?: boolean;
|
||||||
dropdownArrowClassName: string;
|
dropdownArrowClassName: string;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
tooltip: boolean;
|
tooltip: boolean;
|
||||||
@ -51,6 +52,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
} = props;
|
} = props;
|
||||||
@ -60,6 +62,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -111,6 +114,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
} = props;
|
} = props;
|
||||||
@ -120,6 +124,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -268,6 +273,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "border-without-text" ? (
|
) : buttonVariant === "border-without-text" ? (
|
||||||
@ -279,6 +285,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
hideText
|
hideText
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "background-with-text" ? (
|
) : buttonVariant === "background-with-text" ? (
|
||||||
@ -310,6 +317,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "transparent-without-text" ? (
|
) : buttonVariant === "transparent-without-text" ? (
|
||||||
@ -321,6 +329,7 @@ export const CycleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
hideText
|
hideText
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -2,7 +2,7 @@ import React, { useRef, useState } from "react";
|
|||||||
import { Combobox } from "@headlessui/react";
|
import { Combobox } from "@headlessui/react";
|
||||||
import DatePicker from "react-datepicker";
|
import DatePicker from "react-datepicker";
|
||||||
import { usePopper } from "react-popper";
|
import { usePopper } from "react-popper";
|
||||||
import { CalendarDays, X } from "lucide-react";
|
import { Calendar, CalendarDays, X } from "lucide-react";
|
||||||
// hooks
|
// hooks
|
||||||
import { useDropdownKeyDown } from "hooks/use-dropdown-key-down";
|
import { useDropdownKeyDown } from "hooks/use-dropdown-key-down";
|
||||||
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
import useOutsideClickDetector from "hooks/use-outside-click-detector";
|
||||||
@ -23,6 +23,7 @@ type Props = TDropdownProps & {
|
|||||||
onChange: (val: Date | null) => void;
|
onChange: (val: Date | null) => void;
|
||||||
value: Date | string | null;
|
value: Date | string | null;
|
||||||
closeOnSelect?: boolean;
|
closeOnSelect?: boolean;
|
||||||
|
showPlaceholderIcon?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ButtonProps = {
|
type ButtonProps = {
|
||||||
@ -33,9 +34,11 @@ type ButtonProps = {
|
|||||||
isClearable: boolean;
|
isClearable: boolean;
|
||||||
hideIcon?: boolean;
|
hideIcon?: boolean;
|
||||||
hideText?: boolean;
|
hideText?: boolean;
|
||||||
|
isActive?: boolean;
|
||||||
onClear: () => void;
|
onClear: () => void;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
tooltip: boolean;
|
tooltip: boolean;
|
||||||
|
showPlaceholderIcon?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const BorderButton = (props: ButtonProps) => {
|
const BorderButton = (props: ButtonProps) => {
|
||||||
@ -47,6 +50,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
isClearable,
|
isClearable,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
onClear,
|
onClear,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
@ -61,6 +65,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -131,9 +136,11 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
isClearable,
|
isClearable,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
onClear,
|
onClear,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
|
showPlaceholderIcon = false,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -145,11 +152,16 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{!hideIcon && icon}
|
{!hideIcon && icon}
|
||||||
{!hideText && <span className="flex-grow truncate">{date ? renderFormattedDate(date) : placeholder}</span>}
|
{!hideText && <span className="flex-grow truncate">{date ? renderFormattedDate(date) : placeholder}</span>}
|
||||||
|
{showPlaceholderIcon && !date && (
|
||||||
|
<Calendar className="h-2.5 w-2.5 flex-shrink-0 hidden group-hover:inline text-custom-text-400" />
|
||||||
|
)}
|
||||||
|
|
||||||
{isClearable && (
|
{isClearable && (
|
||||||
<X
|
<X
|
||||||
className={cn("h-2 w-2 flex-shrink-0", clearIconClassName)}
|
className={cn("h-2 w-2 flex-shrink-0", clearIconClassName)}
|
||||||
@ -183,6 +195,7 @@ export const DateDropdown: React.FC<Props> = (props) => {
|
|||||||
placement,
|
placement,
|
||||||
tabIndex,
|
tabIndex,
|
||||||
tooltip = false,
|
tooltip = false,
|
||||||
|
showPlaceholderIcon = false,
|
||||||
value,
|
value,
|
||||||
} = props;
|
} = props;
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
@ -246,6 +259,7 @@ export const DateDropdown: React.FC<Props> = (props) => {
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
isClearable={isClearable && isDateSelected}
|
isClearable={isClearable && isDateSelected}
|
||||||
onClear={() => onChange(null)}
|
onClear={() => onChange(null)}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "border-without-text" ? (
|
) : buttonVariant === "border-without-text" ? (
|
||||||
@ -258,6 +272,7 @@ export const DateDropdown: React.FC<Props> = (props) => {
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
isClearable={isClearable && isDateSelected}
|
isClearable={isClearable && isDateSelected}
|
||||||
onClear={() => onChange(null)}
|
onClear={() => onChange(null)}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
hideText
|
hideText
|
||||||
/>
|
/>
|
||||||
@ -296,7 +311,9 @@ export const DateDropdown: React.FC<Props> = (props) => {
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
isClearable={isClearable && isDateSelected}
|
isClearable={isClearable && isDateSelected}
|
||||||
onClear={() => onChange(null)}
|
onClear={() => onChange(null)}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
|
showPlaceholderIcon={showPlaceholderIcon}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "transparent-without-text" ? (
|
) : buttonVariant === "transparent-without-text" ? (
|
||||||
<TransparentButton
|
<TransparentButton
|
||||||
@ -308,8 +325,10 @@ export const DateDropdown: React.FC<Props> = (props) => {
|
|||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
isClearable={isClearable && isDateSelected}
|
isClearable={isClearable && isDateSelected}
|
||||||
onClear={() => onChange(null)}
|
onClear={() => onChange(null)}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
hideText
|
hideText
|
||||||
|
showPlaceholderIcon={showPlaceholderIcon}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</button>
|
</button>
|
||||||
|
@ -31,6 +31,7 @@ type ButtonProps = {
|
|||||||
dropdownArrowClassName: string;
|
dropdownArrowClassName: string;
|
||||||
hideIcon?: boolean;
|
hideIcon?: boolean;
|
||||||
hideText?: boolean;
|
hideText?: boolean;
|
||||||
|
isActive?: boolean;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
tooltip: boolean;
|
tooltip: boolean;
|
||||||
};
|
};
|
||||||
@ -51,6 +52,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
} = props;
|
} = props;
|
||||||
@ -64,6 +66,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -123,6 +126,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
} = props;
|
} = props;
|
||||||
@ -136,6 +140,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -276,6 +281,7 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "border-without-text" ? (
|
) : buttonVariant === "border-without-text" ? (
|
||||||
@ -287,6 +293,7 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
hideText
|
hideText
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "background-with-text" ? (
|
) : buttonVariant === "background-with-text" ? (
|
||||||
@ -318,6 +325,7 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "transparent-without-text" ? (
|
) : buttonVariant === "transparent-without-text" ? (
|
||||||
@ -329,6 +337,7 @@ export const EstimateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
hideText
|
hideText
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -14,6 +14,7 @@ type ButtonProps = {
|
|||||||
placeholder: string;
|
placeholder: string;
|
||||||
hideIcon?: boolean;
|
hideIcon?: boolean;
|
||||||
hideText?: boolean;
|
hideText?: boolean;
|
||||||
|
isActive?: boolean;
|
||||||
tooltip: boolean;
|
tooltip: boolean;
|
||||||
userIds: string | string[] | null;
|
userIds: string | string[] | null;
|
||||||
};
|
};
|
||||||
@ -50,6 +51,7 @@ export const BorderButton = observer((props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
placeholder,
|
placeholder,
|
||||||
userIds,
|
userIds,
|
||||||
tooltip,
|
tooltip,
|
||||||
@ -57,7 +59,7 @@ export const BorderButton = observer((props: ButtonProps) => {
|
|||||||
// store hooks
|
// store hooks
|
||||||
const { getUserDetails } = useMember();
|
const { getUserDetails } = useMember();
|
||||||
|
|
||||||
const isMultiple = Array.isArray(userIds);
|
const isArray = Array.isArray(userIds);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@ -68,13 +70,18 @@ export const BorderButton = observer((props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{!hideIcon && <ButtonAvatars tooltip={tooltip} userIds={userIds} />}
|
{!hideIcon && <ButtonAvatars tooltip={tooltip} userIds={userIds} />}
|
||||||
{!hideText && (
|
{!hideText && (
|
||||||
<span className="flex-grow truncate">
|
<span className="flex-grow truncate text-sm leading-5">
|
||||||
{userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder}
|
{isArray && userIds.length > 0
|
||||||
|
? userIds.length === 1
|
||||||
|
? getUserDetails(userIds[0])?.display_name
|
||||||
|
: ""
|
||||||
|
: placeholder}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{dropdownArrow && (
|
{dropdownArrow && (
|
||||||
@ -99,7 +106,7 @@ export const BackgroundButton = observer((props: ButtonProps) => {
|
|||||||
// store hooks
|
// store hooks
|
||||||
const { getUserDetails } = useMember();
|
const { getUserDetails } = useMember();
|
||||||
|
|
||||||
const isMultiple = Array.isArray(userIds);
|
const isArray = Array.isArray(userIds);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@ -115,8 +122,12 @@ export const BackgroundButton = observer((props: ButtonProps) => {
|
|||||||
>
|
>
|
||||||
{!hideIcon && <ButtonAvatars tooltip={tooltip} userIds={userIds} />}
|
{!hideIcon && <ButtonAvatars tooltip={tooltip} userIds={userIds} />}
|
||||||
{!hideText && (
|
{!hideText && (
|
||||||
<span className="flex-grow truncate">
|
<span className="flex-grow truncate text-sm leading-5">
|
||||||
{userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder}
|
{isArray && userIds.length > 0
|
||||||
|
? userIds.length === 1
|
||||||
|
? getUserDetails(userIds[0])?.display_name
|
||||||
|
: ""
|
||||||
|
: placeholder}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{dropdownArrow && (
|
{dropdownArrow && (
|
||||||
@ -134,6 +145,7 @@ export const TransparentButton = observer((props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
placeholder,
|
placeholder,
|
||||||
userIds,
|
userIds,
|
||||||
tooltip,
|
tooltip,
|
||||||
@ -141,7 +153,7 @@ export const TransparentButton = observer((props: ButtonProps) => {
|
|||||||
// store hooks
|
// store hooks
|
||||||
const { getUserDetails } = useMember();
|
const { getUserDetails } = useMember();
|
||||||
|
|
||||||
const isMultiple = Array.isArray(userIds);
|
const isArray = Array.isArray(userIds);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@ -152,13 +164,18 @@ export const TransparentButton = observer((props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{!hideIcon && <ButtonAvatars tooltip={tooltip} userIds={userIds} />}
|
{!hideIcon && <ButtonAvatars tooltip={tooltip} userIds={userIds} />}
|
||||||
{!hideText && (
|
{!hideText && (
|
||||||
<span className="flex-grow truncate">
|
<span className="flex-grow truncate text-sm leading-5">
|
||||||
{userIds ? (isMultiple ? placeholder : getUserDetails(userIds)?.display_name) : placeholder}
|
{isArray && userIds.length > 0
|
||||||
|
? userIds.length === 1
|
||||||
|
? getUserDetails(userIds[0])?.display_name
|
||||||
|
: ""
|
||||||
|
: placeholder}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{dropdownArrow && (
|
{dropdownArrow && (
|
||||||
|
@ -147,6 +147,7 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "border-without-text" ? (
|
) : buttonVariant === "border-without-text" ? (
|
||||||
@ -157,6 +158,7 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
hideText
|
hideText
|
||||||
/>
|
/>
|
||||||
@ -189,6 +191,7 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "transparent-without-text" ? (
|
) : buttonVariant === "transparent-without-text" ? (
|
||||||
@ -199,6 +202,7 @@ export const ProjectMemberDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
hideText
|
hideText
|
||||||
/>
|
/>
|
||||||
|
@ -38,6 +38,7 @@ type ButtonProps = {
|
|||||||
dropdownArrowClassName: string;
|
dropdownArrowClassName: string;
|
||||||
hideIcon?: boolean;
|
hideIcon?: boolean;
|
||||||
hideText?: boolean;
|
hideText?: boolean;
|
||||||
|
isActive?: boolean;
|
||||||
module: IModule | null;
|
module: IModule | null;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
tooltip: boolean;
|
tooltip: boolean;
|
||||||
@ -50,6 +51,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
module,
|
module,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
@ -60,6 +62,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -110,6 +113,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
module,
|
module,
|
||||||
placeholder,
|
placeholder,
|
||||||
tooltip,
|
tooltip,
|
||||||
@ -120,6 +124,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
||||||
|
{ "bg-custom-background-80": isActive },
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -267,6 +272,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "border-without-text" ? (
|
) : buttonVariant === "border-without-text" ? (
|
||||||
@ -278,6 +284,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
hideText
|
hideText
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "background-with-text" ? (
|
) : buttonVariant === "background-with-text" ? (
|
||||||
@ -309,6 +316,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "transparent-without-text" ? (
|
) : buttonVariant === "transparent-without-text" ? (
|
||||||
@ -320,6 +328,7 @@ export const ModuleDropdown: React.FC<Props> = observer((props) => {
|
|||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
hideText
|
hideText
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -31,6 +31,7 @@ type ButtonProps = {
|
|||||||
dropdownArrowClassName: string;
|
dropdownArrowClassName: string;
|
||||||
hideIcon?: boolean;
|
hideIcon?: boolean;
|
||||||
hideText?: boolean;
|
hideText?: boolean;
|
||||||
|
isActive?: boolean;
|
||||||
highlightUrgent: boolean;
|
highlightUrgent: boolean;
|
||||||
priority: TIssuePriorities;
|
priority: TIssuePriorities;
|
||||||
tooltip: boolean;
|
tooltip: boolean;
|
||||||
@ -181,6 +182,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
highlightUrgent,
|
highlightUrgent,
|
||||||
priority,
|
priority,
|
||||||
tooltip,
|
tooltip,
|
||||||
@ -207,6 +209,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
"px-0.5": hideText,
|
"px-0.5": hideText,
|
||||||
// highlight the whole button if text is hidden and priority is urgent
|
// highlight the whole button if text is hidden and priority is urgent
|
||||||
"bg-red-500 border-red-500": priority === "urgent" && hideText && highlightUrgent,
|
"bg-red-500 border-red-500": priority === "urgent" && hideText && highlightUrgent,
|
||||||
|
"bg-custom-background-80": isActive,
|
||||||
},
|
},
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
@ -312,7 +315,13 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
|
|||||||
as="div"
|
as="div"
|
||||||
ref={dropdownRef}
|
ref={dropdownRef}
|
||||||
tabIndex={tabIndex}
|
tabIndex={tabIndex}
|
||||||
className={cn("h-full", className)}
|
className={cn(
|
||||||
|
"h-full",
|
||||||
|
{
|
||||||
|
"bg-custom-background-80": isOpen,
|
||||||
|
},
|
||||||
|
className
|
||||||
|
)}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
@ -402,6 +411,7 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
|
|||||||
dropdownArrow={dropdownArrow && !disabled}
|
dropdownArrow={dropdownArrow && !disabled}
|
||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "transparent-without-text" ? (
|
) : buttonVariant === "transparent-without-text" ? (
|
||||||
@ -414,6 +424,7 @@ export const PriorityDropdown: React.FC<Props> = (props) => {
|
|||||||
dropdownArrow={dropdownArrow && !disabled}
|
dropdownArrow={dropdownArrow && !disabled}
|
||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
hideText
|
hideText
|
||||||
/>
|
/>
|
||||||
|
@ -30,6 +30,7 @@ type ButtonProps = {
|
|||||||
dropdownArrowClassName: string;
|
dropdownArrowClassName: string;
|
||||||
hideIcon?: boolean;
|
hideIcon?: boolean;
|
||||||
hideText?: boolean;
|
hideText?: boolean;
|
||||||
|
isActive?: boolean;
|
||||||
state: IState | undefined;
|
state: IState | undefined;
|
||||||
tooltip: boolean;
|
tooltip: boolean;
|
||||||
};
|
};
|
||||||
@ -41,6 +42,7 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
state,
|
state,
|
||||||
tooltip,
|
tooltip,
|
||||||
} = props;
|
} = props;
|
||||||
@ -50,6 +52,9 @@ const BorderButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
"h-full flex items-center gap-1.5 border-[0.5px] border-custom-border-300 hover:bg-custom-background-80 rounded text-xs px-2 py-0.5",
|
||||||
|
{
|
||||||
|
"bg-custom-background-80": isActive,
|
||||||
|
},
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -111,6 +116,7 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
dropdownArrowClassName,
|
dropdownArrowClassName,
|
||||||
hideIcon = false,
|
hideIcon = false,
|
||||||
hideText = false,
|
hideText = false,
|
||||||
|
isActive = false,
|
||||||
state,
|
state,
|
||||||
tooltip,
|
tooltip,
|
||||||
} = props;
|
} = props;
|
||||||
@ -120,6 +126,9 @@ const TransparentButton = (props: ButtonProps) => {
|
|||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
"h-full flex items-center gap-1.5 rounded text-xs px-2 py-0.5 hover:bg-custom-background-80",
|
||||||
|
{
|
||||||
|
"bg-custom-background-80": isActive,
|
||||||
|
},
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@ -251,6 +260,7 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrow={dropdownArrow && !disabled}
|
dropdownArrow={dropdownArrow && !disabled}
|
||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "border-without-text" ? (
|
) : buttonVariant === "border-without-text" ? (
|
||||||
@ -260,6 +270,7 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrow={dropdownArrow && !disabled}
|
dropdownArrow={dropdownArrow && !disabled}
|
||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
hideText
|
hideText
|
||||||
/>
|
/>
|
||||||
@ -289,6 +300,7 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrow={dropdownArrow && !disabled}
|
dropdownArrow={dropdownArrow && !disabled}
|
||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
/>
|
/>
|
||||||
) : buttonVariant === "transparent-without-text" ? (
|
) : buttonVariant === "transparent-without-text" ? (
|
||||||
@ -298,6 +310,7 @@ export const StateDropdown: React.FC<Props> = observer((props) => {
|
|||||||
dropdownArrow={dropdownArrow && !disabled}
|
dropdownArrow={dropdownArrow && !disabled}
|
||||||
dropdownArrowClassName={dropdownArrowClassName}
|
dropdownArrowClassName={dropdownArrowClassName}
|
||||||
hideIcon={hideIcon}
|
hideIcon={hideIcon}
|
||||||
|
isActive={isOpen}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
hideText
|
hideText
|
||||||
/>
|
/>
|
||||||
|
@ -64,6 +64,7 @@ export const IssueParentSelect: React.FC<TIssueParentSelect> = observer((props)
|
|||||||
{
|
{
|
||||||
"cursor-not-allowed": disabled,
|
"cursor-not-allowed": disabled,
|
||||||
"hover:bg-custom-background-80": !disabled,
|
"hover:bg-custom-background-80": !disabled,
|
||||||
|
"bg-custom-background-80": isParentIssueModalOpen,
|
||||||
},
|
},
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
@ -72,15 +73,20 @@ export const IssueParentSelect: React.FC<TIssueParentSelect> = observer((props)
|
|||||||
>
|
>
|
||||||
{issue.parent_id && parentIssue ? (
|
{issue.parent_id && parentIssue ? (
|
||||||
<div className="flex items-center gap-1 bg-green-500/20 text-green-700 rounded px-1.5 py-1">
|
<div className="flex items-center gap-1 bg-green-500/20 text-green-700 rounded px-1.5 py-1">
|
||||||
|
<Tooltip tooltipHeading="Title" tooltipContent={parentIssue.name}>
|
||||||
<Link
|
<Link
|
||||||
href={`/${workspaceSlug}/projects/${projectId}/issues/${parentIssue?.id}`}
|
href={`/${workspaceSlug}/projects/${projectId}/issues/${parentIssue?.id}`}
|
||||||
className="text-xs font-medium"
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-xs font-medium mt-0.5"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{parentIssueProjectDetails?.identifier}-{parentIssue.sequence_id}
|
{parentIssueProjectDetails?.identifier}-{parentIssue.sequence_id}
|
||||||
</Link>
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
{!disabled && (
|
{!disabled && (
|
||||||
<Tooltip tooltipContent="Remove">
|
<Tooltip tooltipContent="Remove" position="bottom">
|
||||||
<span
|
<span
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -96,7 +102,15 @@ export const IssueParentSelect: React.FC<TIssueParentSelect> = observer((props)
|
|||||||
) : (
|
) : (
|
||||||
<span className="text-sm text-custom-text-400">Add parent issue</span>
|
<span className="text-sm text-custom-text-400">Add parent issue</span>
|
||||||
)}
|
)}
|
||||||
{!disabled && <Pencil className="h-4 w-4 flex-shrink-0 hidden group-hover:inline" />}
|
{!disabled && (
|
||||||
|
<span
|
||||||
|
className={cn("p-1 flex-shrink-0 opacity-0 group-hover:opacity-100", {
|
||||||
|
"text-custom-text-400": !issue.parent_id && !parentIssue,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Pencil className="h-2.5 w-2.5 flex-shrink-0" />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
import Link from "next/link";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
import { CircleDot, CopyPlus, Pencil, X, XCircle } from "lucide-react";
|
import { CircleDot, CopyPlus, Pencil, X, XCircle } from "lucide-react";
|
||||||
// hooks
|
// hooks
|
||||||
@ -101,18 +102,20 @@ export const IssueRelationSelect: React.FC<TIssueRelationSelect> = observer((pro
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className={cn(
|
className={cn(
|
||||||
"group flex items-center justify-between gap-2 px-2 py-0.5 rounded outline-none",
|
"group flex items-center gap-2 px-2 py-0.5 rounded outline-none",
|
||||||
{
|
{
|
||||||
"cursor-not-allowed": disabled,
|
"cursor-not-allowed": disabled,
|
||||||
"hover:bg-custom-background-80": !disabled,
|
"hover:bg-custom-background-80": !disabled,
|
||||||
|
"bg-custom-background-80": isRelationModalOpen === relationKey,
|
||||||
},
|
},
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
onClick={() => toggleRelationModal(relationKey)}
|
onClick={() => toggleRelationModal(relationKey)}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
>
|
>
|
||||||
|
<div className="flex items-start justify-between w-full">
|
||||||
{relationIssueIds.length > 0 ? (
|
{relationIssueIds.length > 0 ? (
|
||||||
<div className="flex items-center gap-2 flex-wrap">
|
<div className="flex items-center gap-2 py-0.5 flex-wrap">
|
||||||
{relationIssueIds.map((relationIssueId) => {
|
{relationIssueIds.map((relationIssueId) => {
|
||||||
const currentIssue = issueMap[relationIssueId];
|
const currentIssue = issueMap[relationIssueId];
|
||||||
if (!currentIssue) return;
|
if (!currentIssue) return;
|
||||||
@ -122,19 +125,21 @@ export const IssueRelationSelect: React.FC<TIssueRelationSelect> = observer((pro
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={relationIssueId}
|
key={relationIssueId}
|
||||||
className={`group flex items-center gap-1 rounded px-1.5 py-1 ${issueRelationObject[relationKey].className}`}
|
className={`group flex items-center gap-1 rounded px-1.5 pt-1 pb-1 leading-3 hover:bg-custom-background-90 ${issueRelationObject[relationKey].className}`}
|
||||||
>
|
>
|
||||||
<a
|
<Tooltip tooltipHeading="Title" tooltipContent={currentIssue.name}>
|
||||||
|
<Link
|
||||||
href={`/${workspaceSlug}/projects/${projectDetails?.id}/issues/${currentIssue.id}`}
|
href={`/${workspaceSlug}/projects/${projectDetails?.id}/issues/${currentIssue.id}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="text-xs font-medium"
|
className="text-xs font-medium mt-0.5"
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
{`${projectDetails?.identifier}-${currentIssue?.sequence_id}`}
|
{`${projectDetails?.identifier}-${currentIssue?.sequence_id}`}
|
||||||
</a>
|
</Link>
|
||||||
|
</Tooltip>
|
||||||
{!disabled && (
|
{!disabled && (
|
||||||
<Tooltip tooltipContent="Remove">
|
<Tooltip tooltipContent="Remove" position="bottom">
|
||||||
<span
|
<span
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -153,7 +158,16 @@ export const IssueRelationSelect: React.FC<TIssueRelationSelect> = observer((pro
|
|||||||
) : (
|
) : (
|
||||||
<span className="text-sm text-custom-text-400">{issueRelationObject[relationKey].placeholder}</span>
|
<span className="text-sm text-custom-text-400">{issueRelationObject[relationKey].placeholder}</span>
|
||||||
)}
|
)}
|
||||||
{!disabled && <Pencil className="h-4 w-4 flex-shrink-0 hidden group-hover:inline" />}
|
{!disabled && (
|
||||||
|
<span
|
||||||
|
className={cn("p-1 flex-shrink-0 opacity-0 group-hover:opacity-100", {
|
||||||
|
"text-custom-text-400": relationIssueIds.length === 0,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Pencil className="h-2.5 w-2.5 flex-shrink-0" />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -184,7 +184,7 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
projectId={projectId?.toString() ?? ""}
|
projectId={projectId?.toString() ?? ""}
|
||||||
placeholder="Add assignees"
|
placeholder="Add assignees"
|
||||||
multiple
|
multiple
|
||||||
buttonVariant={issue?.assignee_ids?.length > 0 ? "transparent-without-text" : "transparent-with-text"}
|
buttonVariant={issue?.assignee_ids?.length > 1 ? "transparent-without-text" : "transparent-with-text"}
|
||||||
className="w-3/5 flex-grow group"
|
className="w-3/5 flex-grow group"
|
||||||
buttonContainerClassName="w-full text-left"
|
buttonContainerClassName="w-full text-left"
|
||||||
buttonClassName={`text-sm justify-between ${
|
buttonClassName={`text-sm justify-between ${
|
||||||
@ -233,6 +233,7 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
buttonClassName={`text-sm ${issue?.start_date ? "" : "text-custom-text-400"}`}
|
buttonClassName={`text-sm ${issue?.start_date ? "" : "text-custom-text-400"}`}
|
||||||
hideIcon
|
hideIcon
|
||||||
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
||||||
|
showPlaceholderIcon
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -257,6 +258,7 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
buttonClassName={`text-sm ${issue?.target_date ? "" : "text-custom-text-400"}`}
|
buttonClassName={`text-sm ${issue?.target_date ? "" : "text-custom-text-400"}`}
|
||||||
hideIcon
|
hideIcon
|
||||||
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
||||||
|
showPlaceholderIcon
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -332,8 +334,8 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 min-h-8">
|
<div className="flex gap-2 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex gap-1 pt-2 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<RelatedIcon className="h-4 w-4 flex-shrink-0" />
|
<RelatedIcon className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Relates to</span>
|
<span>Relates to</span>
|
||||||
</div>
|
</div>
|
||||||
@ -347,8 +349,8 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 min-h-8">
|
<div className="flex gap-2 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex gap-1 pt-2 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<XCircle className="h-4 w-4 flex-shrink-0" />
|
<XCircle className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Blocking</span>
|
<span>Blocking</span>
|
||||||
</div>
|
</div>
|
||||||
@ -362,8 +364,8 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 min-h-8">
|
<div className="flex gap-2 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex gap-1 pt-2 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<CircleDot className="h-4 w-4 flex-shrink-0" />
|
<CircleDot className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Blocked by</span>
|
<span>Blocked by</span>
|
||||||
</div>
|
</div>
|
||||||
@ -377,8 +379,8 @@ export const IssueDetailsSidebar: React.FC<Props> = observer((props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2 min-h-8">
|
<div className="flex gap-2 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex gap-1 pt-2 w-2/5 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<CopyPlus className="h-4 w-4 flex-shrink-0" />
|
<CopyPlus className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Duplicate of</span>
|
<span>Duplicate of</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -99,7 +99,7 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||||||
projectId={projectId}
|
projectId={projectId}
|
||||||
placeholder="Add assignees"
|
placeholder="Add assignees"
|
||||||
multiple
|
multiple
|
||||||
buttonVariant={issue?.assignee_ids?.length > 0 ? "transparent-without-text" : "transparent-with-text"}
|
buttonVariant={issue?.assignee_ids?.length > 1 ? "transparent-without-text" : "transparent-with-text"}
|
||||||
className="w-3/4 flex-grow group"
|
className="w-3/4 flex-grow group"
|
||||||
buttonContainerClassName="w-full text-left"
|
buttonContainerClassName="w-full text-left"
|
||||||
buttonClassName={`text-sm justify-between ${issue?.assignee_ids.length > 0 ? "" : "text-custom-text-400"}`}
|
buttonClassName={`text-sm justify-between ${issue?.assignee_ids.length > 0 ? "" : "text-custom-text-400"}`}
|
||||||
@ -148,6 +148,7 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||||||
buttonClassName={`text-sm ${issue?.start_date ? "" : "text-custom-text-400"}`}
|
buttonClassName={`text-sm ${issue?.start_date ? "" : "text-custom-text-400"}`}
|
||||||
hideIcon
|
hideIcon
|
||||||
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
||||||
|
showPlaceholderIcon
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -173,6 +174,7 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||||||
buttonClassName={`text-sm ${issue?.target_date ? "" : "text-custom-text-400"}`}
|
buttonClassName={`text-sm ${issue?.target_date ? "" : "text-custom-text-400"}`}
|
||||||
hideIcon
|
hideIcon
|
||||||
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
clearIconClassName="h-3 w-3 hidden group-hover:inline"
|
||||||
|
showPlaceholderIcon
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -251,8 +253,8 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* relates to */}
|
{/* relates to */}
|
||||||
<div className="flex items-center gap-3 min-h-8">
|
<div className="flex gap-3 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex pt-2 gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<RelatedIcon className="h-4 w-4 flex-shrink-0" />
|
<RelatedIcon className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Relates to</span>
|
<span>Relates to</span>
|
||||||
</div>
|
</div>
|
||||||
@ -267,8 +269,8 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* blocking */}
|
{/* blocking */}
|
||||||
<div className="flex items-center gap-3 min-h-8">
|
<div className="flex gap-3 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex pt-2 gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<XCircle className="h-4 w-4 flex-shrink-0" />
|
<XCircle className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Blocking</span>
|
<span>Blocking</span>
|
||||||
</div>
|
</div>
|
||||||
@ -283,8 +285,8 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* blocked by */}
|
{/* blocked by */}
|
||||||
<div className="flex items-center gap-3 min-h-8">
|
<div className="flex gap-3 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex pt-2 gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<CircleDot className="h-4 w-4 flex-shrink-0" />
|
<CircleDot className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Blocked by</span>
|
<span>Blocked by</span>
|
||||||
</div>
|
</div>
|
||||||
@ -299,8 +301,8 @@ export const PeekOverviewProperties: FC<IPeekOverviewProperties> = observer((pro
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* duplicate of */}
|
{/* duplicate of */}
|
||||||
<div className="flex items-center gap-3 min-h-8">
|
<div className="flex gap-3 min-h-8">
|
||||||
<div className="flex items-center gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
<div className="flex pt-2 gap-1 w-1/4 flex-shrink-0 text-sm text-custom-text-300">
|
||||||
<CopyPlus className="h-4 w-4 flex-shrink-0" />
|
<CopyPlus className="h-4 w-4 flex-shrink-0" />
|
||||||
<span>Duplicate of</span>
|
<span>Duplicate of</span>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user