forked from github/plane
Standarding priority icons across the platform (#2776)
This commit is contained in:
parent
002dc7a5f3
commit
2d1536e44d
@ -15,24 +15,42 @@ import { IPriorityIcon } from "./type";
|
|||||||
export const PriorityIcon: React.FC<IPriorityIcon> = ({
|
export const PriorityIcon: React.FC<IPriorityIcon> = ({
|
||||||
priority,
|
priority,
|
||||||
className = "",
|
className = "",
|
||||||
|
transparentBg = false
|
||||||
}) => {
|
}) => {
|
||||||
if (!className || className === "") className = "h-3.5 w-3.5";
|
if (!className || className === "") className = "h-4 w-4";
|
||||||
|
|
||||||
// Convert to lowercase for string comparison
|
// Convert to lowercase for string comparison
|
||||||
const lowercasePriority = priority?.toLowerCase();
|
const lowercasePriority = priority?.toLowerCase();
|
||||||
|
|
||||||
|
//get priority icon
|
||||||
|
const getPriorityIcon = (): React.ReactNode => {
|
||||||
|
switch (lowercasePriority) {
|
||||||
|
case 'urgent':
|
||||||
|
return <AlertCircle className={`text-red-500 ${ transparentBg ? '' : 'p-0.5' } ${className}`} />;
|
||||||
|
case 'high':
|
||||||
|
return <SignalHigh className={`text-orange-500 ${ transparentBg ? '' : 'pl-1' } ${className}`} />;
|
||||||
|
case 'medium':
|
||||||
|
return <SignalMedium className={`text-yellow-500 ${ transparentBg ? '' : 'ml-1.5' } ${className}`} />;
|
||||||
|
case 'low':
|
||||||
|
return <SignalLow className={`text-green-500 ${ transparentBg ? '' : 'ml-2' } ${className}`} />;
|
||||||
|
default:
|
||||||
|
return <Ban className={`text-custom-text-200 ${ transparentBg ? '' : 'p-0.5' } ${className}`} />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{lowercasePriority === "urgent" ? (
|
{ transparentBg ? (
|
||||||
<AlertCircle className={`text-red-500 ${className}`} />
|
getPriorityIcon()
|
||||||
) : lowercasePriority === "high" ? (
|
|
||||||
<SignalHigh className={`text-orange-500 ${className}`} />
|
|
||||||
) : lowercasePriority === "medium" ? (
|
|
||||||
<SignalMedium className={`text-yellow-500 ${className}`} />
|
|
||||||
) : lowercasePriority === "low" ? (
|
|
||||||
<SignalLow className={`text-green-500 ${className}`} />
|
|
||||||
) : (
|
) : (
|
||||||
<Ban className={`text-custom-text-200 ${className}`} />
|
<div className={`grid h-5 w-5 place-items-center rounded border items-center ${
|
||||||
|
lowercasePriority === "urgent"
|
||||||
|
? "border-red-500/20 bg-red-500/20"
|
||||||
|
: "border-custom-border-200"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{ getPriorityIcon() }
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
1
packages/ui/src/icons/type.d.ts
vendored
1
packages/ui/src/icons/type.d.ts
vendored
@ -7,4 +7,5 @@ export type TIssuePriorities = "urgent" | "high" | "medium" | "low" | "none";
|
|||||||
export interface IPriorityIcon {
|
export interface IPriorityIcon {
|
||||||
priority: TIssuePriorities | null;
|
priority: TIssuePriorities | null;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
transparentBg?: boolean | false;
|
||||||
}
|
}
|
||||||
|
@ -42,21 +42,7 @@ export const InboxIssueCard: React.FC<Props> = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2 flex-wrap">
|
<div className="flex items-center gap-2 flex-wrap">
|
||||||
<Tooltip tooltipHeading="Priority" tooltipContent={`${issue.priority ?? "None"}`}>
|
<Tooltip tooltipHeading="Priority" tooltipContent={`${issue.priority ?? "None"}`}>
|
||||||
<div
|
|
||||||
className={`grid h-6 w-6 place-items-center rounded border items-center shadow-sm ${
|
|
||||||
issue.priority === "urgent"
|
|
||||||
? "border-red-500/20 bg-red-500/20"
|
|
||||||
: issue.priority === "high"
|
|
||||||
? "border-orange-500/20 bg-orange-500/20"
|
|
||||||
: issue.priority === "medium"
|
|
||||||
? "border-yellow-500/20 bg-yellow-500/20"
|
|
||||||
: issue.priority === "low"
|
|
||||||
? "border-green-500/20 bg-green-500/20"
|
|
||||||
: "border-custom-border-200"
|
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<PriorityIcon priority={issue.priority ?? null} className="h-3.5 w-3.5" />
|
<PriorityIcon priority={issue.priority ?? null} className="h-3.5 w-3.5" />
|
||||||
</div>
|
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
tooltipHeading="Created on"
|
tooltipHeading="Created on"
|
||||||
|
@ -1,53 +1,15 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { observer } from "mobx-react-lite";
|
import { observer } from "mobx-react-lite";
|
||||||
|
|
||||||
|
// ui
|
||||||
|
import { PriorityIcon } from "@plane/ui";
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { FilterHeader, FilterOption } from "components/issues";
|
import { FilterHeader, FilterOption } from "components/issues";
|
||||||
// icons
|
|
||||||
import { AlertCircle, SignalHigh, SignalMedium, SignalLow, Ban } from "lucide-react";
|
|
||||||
// constants
|
// constants
|
||||||
import { ISSUE_PRIORITIES } from "constants/issue";
|
import { ISSUE_PRIORITIES } from "constants/issue";
|
||||||
|
|
||||||
const PriorityIcons = ({
|
|
||||||
priority,
|
|
||||||
size = 12,
|
|
||||||
strokeWidth = 1.5,
|
|
||||||
}: {
|
|
||||||
priority: string;
|
|
||||||
size?: number;
|
|
||||||
strokeWidth?: number;
|
|
||||||
}) => {
|
|
||||||
if (priority === "urgent")
|
|
||||||
return (
|
|
||||||
<div className="flex-shrink-0 rounded-sm overflow-hidden w-5 h-5 border border-red-500 bg-red-500 text-white flex justify-center items-center">
|
|
||||||
<AlertCircle size={size} strokeWidth={strokeWidth} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
if (priority === "high")
|
|
||||||
return (
|
|
||||||
<div className="flex-shrink-0 rounded-sm overflow-hidden w-5 h-5 border border-custom-border-200 text-red-500 flex justify-center items-center pl-1">
|
|
||||||
<SignalHigh size={size} strokeWidth={strokeWidth} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
if (priority === "medium")
|
|
||||||
return (
|
|
||||||
<div className="flex-shrink-0 rounded-sm overflow-hidden w-5 h-5 border border-custom-border-200 text-orange-500 flex justify-center items-center pl-1">
|
|
||||||
<SignalMedium size={size} strokeWidth={strokeWidth} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
if (priority === "low")
|
|
||||||
return (
|
|
||||||
<div className="flex-shrink-0 rounded-sm overflow-hidden w-5 h-5 border border-custom-border-200 text-green-500 flex justify-center items-center pl-1">
|
|
||||||
<SignalLow size={size} strokeWidth={strokeWidth} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
return (
|
|
||||||
<div className="flex-shrink-0 rounded-sm overflow-hidden w-5 h-5 border border-custom-border-200 text-custom-text-400 flex justify-center items-center">
|
|
||||||
<Ban size={size} strokeWidth={strokeWidth} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
appliedFilters: string[] | null;
|
appliedFilters: string[] | null;
|
||||||
handleUpdate: (val: string) => void;
|
handleUpdate: (val: string) => void;
|
||||||
@ -78,7 +40,7 @@ export const FilterPriority: React.FC<Props> = observer((props) => {
|
|||||||
key={priority.key}
|
key={priority.key}
|
||||||
isChecked={appliedFilters?.includes(priority.key) ? true : false}
|
isChecked={appliedFilters?.includes(priority.key) ? true : false}
|
||||||
onClick={() => handleUpdate(priority.key)}
|
onClick={() => handleUpdate(priority.key)}
|
||||||
icon={<PriorityIcons priority={priority.key} />}
|
icon={<PriorityIcon priority={priority.key} className="h-3.5 w-3.5" />}
|
||||||
title={priority.title}
|
title={priority.title}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
|
@ -5,6 +5,9 @@ import { AlertCircle, SignalHigh, SignalMedium, SignalLow, Ban } from "lucide-re
|
|||||||
import { HeaderGroupByCard } from "./group-by-card";
|
import { HeaderGroupByCard } from "./group-by-card";
|
||||||
import { HeaderSubGroupByCard } from "./sub-group-by-card";
|
import { HeaderSubGroupByCard } from "./sub-group-by-card";
|
||||||
|
|
||||||
|
// Icons
|
||||||
|
import { PriorityIcon } from "@plane/ui";
|
||||||
|
|
||||||
export interface IPriorityHeader {
|
export interface IPriorityHeader {
|
||||||
column_id: string;
|
column_id: string;
|
||||||
column_value: any;
|
column_value: any;
|
||||||
@ -16,32 +19,6 @@ export interface IPriorityHeader {
|
|||||||
handleKanBanToggle: any;
|
handleKanBanToggle: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Icon = ({ priority }: any) => (
|
|
||||||
<div className="w-full h-full">
|
|
||||||
{priority === "urgent" ? (
|
|
||||||
<div className="border border-red-500 bg-red-500 text-white w-full h-full overflow-hidden flex justify-center items-center rounded-sm">
|
|
||||||
<AlertCircle size={14} strokeWidth={2} />
|
|
||||||
</div>
|
|
||||||
) : priority === "high" ? (
|
|
||||||
<div className="border border-red-500/20 bg-red-500/10 text-red-500 w-full h-full overflow-hidden flex justify-center items-center rounded-sm">
|
|
||||||
<SignalHigh size={14} strokeWidth={2} className="pl-[3px]" />
|
|
||||||
</div>
|
|
||||||
) : priority === "medium" ? (
|
|
||||||
<div className="border border-orange-500/20 bg-orange-500/10 text-orange-500 w-full h-full overflow-hidden flex justify-center items-center rounded-sm">
|
|
||||||
<SignalMedium size={14} strokeWidth={2} className="pl-[3px]" />
|
|
||||||
</div>
|
|
||||||
) : priority === "low" ? (
|
|
||||||
<div className="border border-green-500/20 bg-green-500/10 text-green-500 w-full h-full overflow-hidden flex justify-center items-center rounded-sm">
|
|
||||||
<SignalLow size={14} strokeWidth={2} className="pl-[3px]" />
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="border border-custom-border-400/20 bg-custom-text-400/10 text-custom-text-400 w-full h-full overflow-hidden flex justify-center items-center rounded-sm">
|
|
||||||
<Ban size={14} strokeWidth={2} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
export const PriorityHeader: FC<IPriorityHeader> = observer((props) => {
|
export const PriorityHeader: FC<IPriorityHeader> = observer((props) => {
|
||||||
const {
|
const {
|
||||||
column_id,
|
column_id,
|
||||||
@ -62,7 +39,7 @@ export const PriorityHeader: FC<IPriorityHeader> = observer((props) => {
|
|||||||
(sub_group_by && header_type === "sub_group_by" ? (
|
(sub_group_by && header_type === "sub_group_by" ? (
|
||||||
<HeaderSubGroupByCard
|
<HeaderSubGroupByCard
|
||||||
column_id={column_id}
|
column_id={column_id}
|
||||||
icon={<Icon priority={priority?.key} />}
|
icon={<PriorityIcon priority={priority?.key} />}
|
||||||
title={priority?.title || ""}
|
title={priority?.title || ""}
|
||||||
count={issues_count}
|
count={issues_count}
|
||||||
kanBanToggle={kanBanToggle}
|
kanBanToggle={kanBanToggle}
|
||||||
@ -73,7 +50,7 @@ export const PriorityHeader: FC<IPriorityHeader> = observer((props) => {
|
|||||||
sub_group_by={sub_group_by}
|
sub_group_by={sub_group_by}
|
||||||
group_by={group_by}
|
group_by={group_by}
|
||||||
column_id={column_id}
|
column_id={column_id}
|
||||||
icon={<Icon priority={priority?.key} />}
|
icon={<PriorityIcon priority={priority?.key} />}
|
||||||
title={priority?.title || ""}
|
title={priority?.title || ""}
|
||||||
count={issues_count}
|
count={issues_count}
|
||||||
kanBanToggle={kanBanToggle}
|
kanBanToggle={kanBanToggle}
|
||||||
|
@ -17,7 +17,7 @@ export const SidebarPrioritySelect: React.FC<Props> = ({ value, onChange, disabl
|
|||||||
<CustomSelect
|
<CustomSelect
|
||||||
customButton={
|
customButton={
|
||||||
<div
|
<div
|
||||||
className={`flex items-center gap-1.5 text-left text-xs capitalize rounded px-2.5 py-0.5 ${
|
className={`flex items-center gap-1 text-left text-xs capitalize rounded px-2 py-0.5 ${
|
||||||
value === "urgent"
|
value === "urgent"
|
||||||
? "border-red-500/20 bg-red-500/20 text-red-500"
|
? "border-red-500/20 bg-red-500/20 text-red-500"
|
||||||
: value === "high"
|
: value === "high"
|
||||||
@ -29,8 +29,8 @@ export const SidebarPrioritySelect: React.FC<Props> = ({ value, onChange, disabl
|
|||||||
: "bg-custom-background-80 border-custom-border-200 text-custom-text-200"
|
: "bg-custom-background-80 border-custom-border-200 text-custom-text-200"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className="grid place-items-center -my-1">
|
<span className="flex items-center justify-center h-4 w-4 overflow-hidden">
|
||||||
<PriorityIcon priority={value} className="h-3.5 w-3.5" />
|
<PriorityIcon priority={value} transparentBg={true} className={`w-3.5 h-3.5 ${(value === "urgent" || value === "none") ? 'p-0.5' : '-mt-1'} `} />
|
||||||
</span>
|
</span>
|
||||||
<span>{value ?? "None"}</span>
|
<span>{value ?? "None"}</span>
|
||||||
</div>
|
</div>
|
||||||
@ -43,7 +43,7 @@ export const SidebarPrioritySelect: React.FC<Props> = ({ value, onChange, disabl
|
|||||||
{PRIORITIES.map((option) => (
|
{PRIORITIES.map((option) => (
|
||||||
<CustomSelect.Option key={option} value={option} className="capitalize">
|
<CustomSelect.Option key={option} value={option} className="capitalize">
|
||||||
<>
|
<>
|
||||||
<PriorityIcon priority={option} className="h-3.5 w-3.5" />
|
<PriorityIcon priority={option} />
|
||||||
{option ?? "None"}
|
{option ?? "None"}
|
||||||
</>
|
</>
|
||||||
</CustomSelect.Option>
|
</CustomSelect.Option>
|
||||||
|
@ -32,7 +32,7 @@ export const PrioritySelect: React.FC<Props> = ({
|
|||||||
optionsClassName = "",
|
optionsClassName = "",
|
||||||
placement,
|
placement,
|
||||||
showTitle = false,
|
showTitle = false,
|
||||||
highlightUrgentPriority = true,
|
//highlightUrgentPriority = true,
|
||||||
hideDropdownArrow = false,
|
hideDropdownArrow = false,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
}) => {
|
}) => {
|
||||||
@ -74,7 +74,7 @@ export const PrioritySelect: React.FC<Props> = ({
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<PriorityIcon
|
<PriorityIcon
|
||||||
priority={value}
|
priority={value}
|
||||||
className={`h-3.5 w-3.5 ${value === "urgent" ? (highlightUrgentPriority ? "text-white" : "text-red-500") : ""}`}
|
className={`h-3.5 w-3.5`}
|
||||||
/>
|
/>
|
||||||
{showTitle && <span className="capitalize text-xs">{value}</span>}
|
{showTitle && <span className="capitalize text-xs">{value}</span>}
|
||||||
</div>
|
</div>
|
||||||
@ -93,19 +93,7 @@ export const PrioritySelect: React.FC<Props> = ({
|
|||||||
<button
|
<button
|
||||||
ref={setReferenceElement}
|
ref={setReferenceElement}
|
||||||
type="button"
|
type="button"
|
||||||
className={`flex items-center justify-between gap-1 h-full w-full text-xs rounded border-[0.5px] ${
|
className={`flex items-center justify-between gap-1 h-full w-full !p-0 ${disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer"} ${buttonClassName}`}
|
||||||
value === "urgent"
|
|
||||||
? highlightUrgentPriority
|
|
||||||
? "border-red-500/20 bg-red-500"
|
|
||||||
: "border-custom-border-300"
|
|
||||||
: "border-custom-border-300"
|
|
||||||
} ${
|
|
||||||
!disabled
|
|
||||||
? `${
|
|
||||||
value === "urgent" && highlightUrgentPriority ? "hover:bg-red-400" : "hover:bg-custom-background-80"
|
|
||||||
}`
|
|
||||||
: ""
|
|
||||||
} ${disabled ? "cursor-not-allowed text-custom-text-200" : "cursor-pointer"} ${buttonClassName}`}
|
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
{!hideDropdownArrow && !disabled && <ChevronDown className="h-2.5 w-2.5" aria-hidden="true" />}
|
{!hideDropdownArrow && !disabled && <ChevronDown className="h-2.5 w-2.5" aria-hidden="true" />}
|
||||||
|
Loading…
Reference in New Issue
Block a user