Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 23 additions & 27 deletions apps/space/components/issues/issue-layouts/properties/labels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,34 @@ export const IssueBlockLabels = observer(function IssueBlockLabels({ labelIds, s
</Tooltip>
);

const shownLabels = labels.slice(0, 2);
const hiddenCount = labels.length - shownLabels.length;

return (
<div className="flex h-5 w-full flex-wrap items-center gap-2 overflow-hidden">
{labels.length <= 2 ? (
<>
{labels.map((label) => (
<Tooltip key={label.id} position="top" tooltipHeading="Labels" tooltipContent={label?.name ?? ""}>
<div
key={label?.id}
className={`flex h-full max-w-full flex-shrink-0 items-center overflow-hidden rounded-sm border-[0.5px] border-strong px-2.5 py-1 text-11`}
>
<div className="flex max-w-full items-center gap-1.5 overflow-hidden text-secondary">
<span
className="h-2 w-2 flex-shrink-0 rounded-full"
style={{
backgroundColor: label?.color ?? "#000000",
}}
/>
<div className="line-clamp-1 inline-block w-auto max-w-[100px] truncate">{label?.name}</div>
</div>
</div>
</Tooltip>
))}
</>
) : (
{shownLabels.map((label) => (
<Tooltip key={label.id} position="top" tooltipHeading="Labels" tooltipContent={label?.name ?? ""}>
<div
className={`flex h-full max-w-full flex-shrink-0 items-center overflow-hidden rounded-sm border-[0.5px] border-strong px-2.5 py-1 text-11`}
>
<div className="flex max-w-full items-center gap-1.5 overflow-hidden text-secondary">
<span
className="h-2 w-2 flex-shrink-0 rounded-full"
style={{
backgroundColor: label?.color ?? "#000000",
}}
/>
<div className="line-clamp-1 inline-block w-auto max-w-[100px] truncate">{label?.name}</div>
</div>
</div>
</Tooltip>
))}
{hiddenCount > 0 && (
<div
className={`cursor-not-allowed" flex h-full flex-shrink-0 items-center rounded-sm border-[0.5px] border-strong px-2.5 py-1 text-11`}
className={`flex h-full flex-shrink-0 cursor-not-allowed items-center rounded-sm border-[0.5px] border-strong px-2.5 py-1 text-11`}
>
<Tooltip position="top" tooltipHeading="Labels" tooltipContent={labelsString}>
<div className="flex h-full items-center gap-1.5 text-secondary">
<span className="h-2 w-2 flex-shrink-0 rounded-full bg-accent-primary" />
{`${labels.length} Labels`}
</div>
<div className="flex h-full items-center gap-1.5 text-secondary">{`+${hiddenCount}`}</div>
</Tooltip>
</div>
)}
Expand Down
78 changes: 55 additions & 23 deletions apps/web/core/components/issues/issue-layouts/properties/labels.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,35 +81,66 @@ type LabelSummaryProps = {
disabled?: boolean;
projectLabels: IIssueLabel[];
value: string[];
maxRender: number;
};

function LabelSummary({ isMobile, fullWidth, noLabelBorder, disabled, projectLabels, value }: LabelSummaryProps) {
function LabelSummary({
isMobile,
fullWidth,
noLabelBorder,
disabled,
projectLabels,
value,
maxRender,
}: LabelSummaryProps) {
const { t } = useTranslation();
// labels the work item actually has, in project order
const selectedLabels = projectLabels?.filter((l) => value.includes(l?.id)) ?? [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React Doctor · react-doctor/js-set-map-lookups (warning)

This scales poorly because array.includes() inside a loop scans the whole list every time. Use a Set for constant-time lookups.

Fix → Use a Set or Map when you check for the same items over and over. Array.includes/find scans the whole list each time

Docs

const shownLabels = selectedLabels.slice(0, maxRender);
const hiddenCount = value.length - shownLabels.length;

return (
<div
className={cn(
"flex h-5 flex-shrink-0 items-center justify-center rounded-sm px-2.5 text-caption-sm-regular",
fullWidth && "w-full",
noLabelBorder ? "rounded-none" : "border-[0.5px] border-strong",
disabled ? "cursor-not-allowed" : "cursor-pointer"
)}
<Tooltip
isMobile={isMobile}
position="top"
tooltipHeading={t("common.labels")}
tooltipContent={selectedLabels.map((l) => l?.name).join(", ")}
renderByDefault={false}
>
<Tooltip
isMobile={isMobile}
position="top"
tooltipHeading={t("common.labels")}
tooltipContent={projectLabels
?.filter((l) => value.includes(l?.id))
.map((l) => l?.name)
.join(", ")}
renderByDefault={false}
<div
className={cn(
"flex h-5 max-w-full flex-shrink-0 items-center gap-1",
fullWidth && "w-full",
disabled ? "cursor-not-allowed" : "cursor-pointer"
)}
>
<div className="flex h-full items-center gap-1.5 text-secondary">
<span className="h-2 w-2 flex-shrink-0 rounded-full bg-accent-primary" />
{`${value.length} Labels`}
</div>
</Tooltip>
</div>
{shownLabels.map((label) => (
<div
key={label.id}
className={cn(
"flex h-full max-w-[140px] items-center gap-1.5 rounded-sm px-2.5 text-caption-sm-regular text-secondary",
noLabelBorder ? "rounded-none" : "border-[0.5px] border-strong"
)}
>
<span
className="h-2 w-2 flex-shrink-0 rounded-full"
style={{ backgroundColor: label?.color ?? "#000000" }}
/>
<span className="truncate">{label?.name}</span>
</div>
))}
{hiddenCount > 0 && (
<div
className={cn(
"flex h-full flex-shrink-0 items-center rounded-sm px-2.5 text-caption-sm-regular text-secondary",
noLabelBorder ? "rounded-none" : "border-[0.5px] border-strong"
)}
>
{`+${hiddenCount}`}
</div>
)}
</div>
</Tooltip>
);
}

Expand Down Expand Up @@ -254,6 +285,7 @@ export const IssuePropertyLabels = observer(function IssuePropertyLabels(props:
disabled={disabled}
projectLabels={projectLabels}
value={value}
maxRender={maxRender}
/>
}
/>
Expand Down
74 changes: 35 additions & 39 deletions apps/web/core/components/issues/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,47 +15,43 @@ type Props = {

export function ViewIssueLabel({ labelDetails, maxRender = 1 }: Props) {
const { isMobile } = usePlatformOS();

if (!labelDetails || labelDetails.length === 0) return null;

const shownLabels = labelDetails.slice(0, maxRender);
const hiddenCount = labelDetails.length - shownLabels.length;

return (
<>
{labelDetails?.length > 0 ? (
labelDetails.length <= maxRender ? (
<>
{labelDetails.map((label) => (
<div
key={label.id}
className="shadow-sm flex flex-shrink-0 cursor-default items-center rounded-md border border-strong px-2.5 py-1 text-11"
>
<Tooltip position="top" tooltipHeading="Label" tooltipContent={label.name} isMobile={isMobile}>
<div className="flex items-center gap-1.5 text-secondary">
<span
className="h-2 w-2 flex-shrink-0 rounded-full"
style={{
backgroundColor: label?.color ?? "#000000",
}}
/>
{label.name}
</div>
</Tooltip>
</div>
))}
</>
) : (
<div className="shadow-sm flex flex-shrink-0 cursor-default items-center rounded-md border border-strong px-2.5 py-1 text-11">
<Tooltip
position="top"
tooltipHeading="Labels"
tooltipContent={labelDetails.map((l) => l.name).join(", ")}
isMobile={isMobile}
>
<div className="flex items-center gap-1.5 text-secondary">
<span className="h-2 w-2 flex-shrink-0 rounded-full bg-accent-primary" />
{`${labelDetails.length} Labels`}
</div>
</Tooltip>
</div>
)
) : (
""
{shownLabels.map((label) => (
<div
key={label.id}
className="shadow-sm flex max-w-[140px] flex-shrink-0 cursor-default items-center rounded-md border border-strong px-2.5 py-1 text-11"
>
<Tooltip position="top" tooltipHeading="Label" tooltipContent={label.name} isMobile={isMobile}>
<div className="flex items-center gap-1.5 text-secondary">
<span
className="h-2 w-2 flex-shrink-0 rounded-full"
style={{
backgroundColor: label?.color ?? "#000000",
}}
/>
<span className="truncate">{label.name}</span>
</div>
</Tooltip>
</div>
))}
{hiddenCount > 0 && (
<div className="shadow-sm flex flex-shrink-0 cursor-default items-center rounded-md border border-strong px-2.5 py-1 text-11">
<Tooltip
position="top"
tooltipHeading="Labels"
tooltipContent={labelDetails.map((l) => l.name).join(", ")}
isMobile={isMobile}
>
<div className="flex items-center gap-1.5 text-secondary">{`+${hiddenCount}`}</div>
</Tooltip>
</div>
)}
</>
);
Expand Down
Loading
Loading