[WEB-6702] feat: redesign intake action buttons and use design tokens (#6403)

* feat: CheckCircleFilledIcon and CloseCircleFilledIcon added to propel

* feat: intake action button and tokens updated

* chore: code refactoring
This commit is contained in:
Anmol Singh Bhatia
2026-03-24 14:06:12 +05:30
committed by GitHub
parent 8b95eca085
commit 31ea40587e
6 changed files with 165 additions and 75 deletions
@@ -14,12 +14,22 @@
import type { FC } from "react";
import { useCallback, useEffect, useState } from "react";
import { observer } from "mobx-react";
import { CircleCheck, CircleX, Clock, FileStack, MoveRight } from "lucide-react";
import { Clock, FileStack, MoreHorizontal, MoveRight } from "lucide-react";
// plane imports
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
import { Button } from "@plane/propel/button";
import { LinkIcon, CopyIcon, NewTabIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } from "@plane/propel/icons";
import { IconButton, getIconButtonStyling } from "@plane/propel/icon-button";
import {
LinkIcon,
CopyIcon,
NewTabIcon,
TrashIcon,
ChevronDownIcon,
ChevronUpIcon,
CheckCircleFilledIcon,
CloseCircleFilledIcon,
} from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { TNameDescriptionLoader, IInboxIssueStore } from "@plane/types";
import { EInboxIssueStatus } from "@plane/types";
@@ -316,73 +326,70 @@ export const InboxIssueActionsHeader = observer(function InboxIssueActionsHeader
<div className="flex items-center gap-2">
{!isNotificationEmbed && (
<div className="flex items-center gap-x-2">
<button
type="button"
className="rounded-sm border border-subtle p-1.5"
<IconButton
variant="secondary"
size="lg"
icon={ChevronUpIcon}
aria-label="Previous work item"
onClick={() => handleInboxIssueNavigation("prev")}
>
<ChevronUpIcon height={14} width={14} strokeWidth={2} />
</button>
<button
type="button"
className="rounded-sm border border-subtle p-1.5"
/>
<IconButton
variant="secondary"
size="lg"
icon={ChevronDownIcon}
aria-label="Next work item"
onClick={() => handleInboxIssueNavigation("next")}
>
<ChevronDownIcon height={14} width={14} strokeWidth={2} />
</button>
/>
</div>
)}
<div className="flex flex-wrap items-center gap-2">
{canMarkAsAccepted && (
<div className="shrink-0">
<Button
variant="secondary"
prependIcon={<CircleCheck className="w-3 h-3" />}
className="text-on-color border border-success-strong bg-success-primary focus:bg-success-primary focus:text-success-primary hover:bg-success-primary"
onClick={() =>
handleActionWithPermission(
isProjectAdmin,
() => setAcceptIssueModal(true),
t("inbox_issue.errors.accept_permission")
)
}
>
{t("inbox_issue.actions.accept")}
</Button>
</div>
<Button
variant="secondary"
size="lg"
onClick={() =>
handleActionWithPermission(
isProjectAdmin,
() => setAcceptIssueModal(true),
t("inbox_issue.errors.accept_permission")
)
}
>
<CheckCircleFilledIcon className="size-4 shrink-0 text-success-secondary" />
{t("inbox_issue.actions.accept")}
</Button>
)}
{canMarkAsDeclined && (
<div className="shrink-0">
<Button
variant="secondary"
prependIcon={<CircleX className="w-3 h-3" />}
className="text-on-color border border-danger-strong bg-danger-primary focus:bg-danger-primary focus:text-danger-primary hover:bg-danger-primary-hover"
onClick={() =>
handleActionWithPermission(
isProjectAdmin,
() => setDeclineIssueModal(true),
t("inbox_issue.errors.decline_permission")
)
}
>
{t("inbox_issue.actions.decline")}
</Button>
</div>
<Button
variant="secondary"
size="lg"
onClick={() =>
handleActionWithPermission(
isProjectAdmin,
() => setDeclineIssueModal(true),
t("inbox_issue.errors.decline_permission")
)
}
>
<CloseCircleFilledIcon className="size-4 shrink-0 text-danger-secondary" />
{t("inbox_issue.actions.decline")}
</Button>
)}
{isAcceptedOrDeclined ? (
<div className="flex items-center gap-2">
<Button
variant="secondary"
size="lg"
prependIcon={<LinkIcon className="h-2.5 w-2.5" />}
onClick={() => handleCopyIssueLink(workItemLink)}
>
{t("inbox_issue.actions.copy")}
</Button>
<ControlLink href={workItemLink} onClick={() => router.push(workItemLink)} target="_self">
<Button variant="secondary" prependIcon={<NewTabIcon className="h-2.5 w-2.5" />}>
<Button variant="secondary" size="lg" prependIcon={<NewTabIcon className="h-2.5 w-2.5" />}>
{t("inbox_issue.actions.open")}
</Button>
</ControlLink>
@@ -390,7 +397,11 @@ export const InboxIssueActionsHeader = observer(function InboxIssueActionsHeader
) : (
<>
{isAllowed && (
<CustomMenu verticalEllipsis placement="bottom-start">
<CustomMenu
customButton={<MoreHorizontal className="size-4" />}
customButtonClassName={getIconButtonStyling("secondary", "lg")}
placement="bottom-start"
>
{canMarkAsAccepted && (
<CustomMenu.MenuItem
onClick={() =>
@@ -12,8 +12,17 @@
*/
import { observer } from "mobx-react";
import { CircleCheck, CircleX, Clock, FileStack, PanelLeft, MoveRight } from "lucide-react";
import { LinkIcon, NewTabIcon, TrashIcon, ChevronDownIcon, ChevronUpIcon } from "@plane/propel/icons";
import { Clock, FileStack, MoreHorizontal, PanelLeft, MoveRight } from "lucide-react";
import { IconButton, getIconButtonStyling } from "@plane/propel/icon-button";
import {
LinkIcon,
NewTabIcon,
TrashIcon,
ChevronDownIcon,
ChevronUpIcon,
CheckCircleFilledIcon,
CloseCircleFilledIcon,
} from "@plane/propel/icons";
import type { TNameDescriptionLoader, IInboxIssueStore } from "@plane/types";
import { Header, CustomMenu, EHeaderVariant } from "@plane/ui";
import { cn, findHowManyDaysLeft, generateWorkItemLink } from "@plane/utils";
@@ -107,20 +116,20 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
/>
<div className="flex items-center gap-2 w-full bg-surface-1 z-[15]">
<div className="flex items-center gap-x-2">
<button
type="button"
className="rounded-sm border border-subtle p-1.5"
<IconButton
variant="secondary"
size="lg"
icon={ChevronUpIcon}
aria-label="Previous work item"
onClick={() => handleInboxIssueNavigation("prev")}
>
<ChevronUpIcon height={14} width={14} strokeWidth={2} />
</button>
<button
type="button"
className="rounded-sm border border-subtle p-1.5"
/>
<IconButton
variant="secondary"
size="lg"
icon={ChevronDownIcon}
aria-label="Next work item"
onClick={() => handleInboxIssueNavigation("next")}
>
<ChevronDownIcon height={14} width={14} strokeWidth={2} />
</button>
/>
</div>
<div className="flex items-center gap-4">
<InboxIssueStatus inboxIssue={inboxIssue} iconSize={12} />
@@ -129,7 +138,11 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
</div>
</div>
<div className="ml-auto">
<CustomMenu verticalEllipsis placement="bottom-start">
<CustomMenu
customButton={<MoreHorizontal className="size-4" />}
customButtonClassName={getIconButtonStyling("secondary", "lg")}
placement="bottom-start"
>
{isAcceptedOrDeclined && (
<CustomMenu.MenuItem onClick={handleCopyIssueLink}>
<div className="flex items-center gap-2">
@@ -188,8 +201,8 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
)
}
>
<div className="flex items-center gap-2 text-success-primary">
<CircleCheck size={14} strokeWidth={2} />
<div className="flex items-center gap-2 text-success-secondary">
<CheckCircleFilledIcon width={14} height={14} />
Accept
</div>
</CustomMenu.MenuItem>
@@ -204,8 +217,8 @@ export const InboxIssueActionsMobileHeader = observer(function InboxIssueActions
)
}
>
<div className="flex items-center gap-2 text-danger-primary">
<CircleX size={14} strokeWidth={2} />
<div className="flex items-center gap-2 text-danger-secondary">
<CloseCircleFilledIcon width={14} height={14} />
Decline
</div>
</CustomMenu.MenuItem>
@@ -20,28 +20,28 @@ import { cn } from "@plane/utils";
export const ICON_PROPERTIES = {
[EInboxIssueStatus.PENDING]: {
icon: AlertTriangle,
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "text-[#AB6400]"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-[#FFF7C2]"),
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "text-warning-primary"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-warning-subtle"),
},
[EInboxIssueStatus.DECLINED]: {
icon: XCircle,
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "text-[#CE2C31]"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-[#FEEBEC]"),
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "text-danger-primary"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-danger-subtle"),
},
[EInboxIssueStatus.SNOOZED]: {
icon: Clock,
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "text-danger-primary" : "text-placeholder"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "bg-danger-subtle" : "bg-[#E0E1E6]"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "bg-danger-subtle" : "bg-layer-3"),
},
[EInboxIssueStatus.ACCEPTED]: {
icon: CheckCircle2,
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "text-[#3E9B4F]"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-[#E9F6E9]"),
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "text-success-primary"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-success-subtle"),
},
[EInboxIssueStatus.DUPLICATE]: {
icon: CopyIcon,
textColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "text-secondary"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-gray-500/10"),
bgColor: (snoozeDatePassed: boolean = false) => (snoozeDatePassed ? "" : "bg-layer-3"),
},
};
export function InboxStatusIcon({
@@ -0,0 +1,32 @@
/**
* SPDX-FileCopyrightText: 2023-present Plane Software, Inc.
* SPDX-License-Identifier: LicenseRef-Plane-Commercial
*
* Licensed under the Plane Commercial License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://plane.so/legals/eula
*
* DO NOT remove or modify this notice.
* NOTICE: Proprietary and confidential. Unauthorized use or distribution is prohibited.
*/
import * as React from "react";
import { IconWrapper } from "../icon-wrapper";
import type { ISvgIcons } from "../type";
export const CheckCircleFilledIcon: React.FC<ISvgIcons> = ({ color = "currentColor", ...rest }) => {
const clipPathId = React.useId();
return (
<IconWrapper color={color} clipPathId={clipPathId} {...rest}>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.99984 0.666992C3.94975 0.666992 0.666504 3.95024 0.666504 8.00033C0.666504 12.0504 3.94975 15.3337 7.99984 15.3337C12.0499 15.3337 15.3332 12.0504 15.3332 8.00033C15.3332 3.95024 12.0499 0.666992 7.99984 0.666992ZM11.4712 6.47173C11.7316 6.21138 11.7316 5.78927 11.4712 5.52892C11.2109 5.26857 10.7888 5.26857 10.5284 5.52892L6.99984 9.05752L5.47124 7.52892C5.21089 7.26857 4.78878 7.26857 4.52843 7.52892C4.26808 7.78927 4.26808 8.21138 4.52843 8.47173L6.52843 10.4717C6.78878 10.7321 7.21089 10.7321 7.47124 10.4717L11.4712 6.47173Z"
fill={color}
/>
</IconWrapper>
);
};
@@ -0,0 +1,32 @@
/**
* SPDX-FileCopyrightText: 2023-present Plane Software, Inc.
* SPDX-License-Identifier: LicenseRef-Plane-Commercial
*
* Licensed under the Plane Commercial License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* https://plane.so/legals/eula
*
* DO NOT remove or modify this notice.
* NOTICE: Proprietary and confidential. Unauthorized use or distribution is prohibited.
*/
import * as React from "react";
import { IconWrapper } from "../icon-wrapper";
import type { ISvgIcons } from "../type";
export const CloseCircleFilledIcon: React.FC<ISvgIcons> = ({ color = "currentColor", ...rest }) => {
const clipPathId = React.useId();
return (
<IconWrapper color={color} clipPathId={clipPathId} {...rest}>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.99984 0.666992C3.94975 0.666992 0.666504 3.95024 0.666504 8.00033C0.666504 12.0504 3.94975 15.3337 7.99984 15.3337C12.0499 15.3337 15.3332 12.0504 15.3332 8.00033C15.3332 3.95024 12.0499 0.666992 7.99984 0.666992ZM10.4712 5.52892C10.7316 5.78927 10.7316 6.21138 10.4712 6.47173L8.94265 8.00033L10.4712 9.52892C10.7316 9.78927 10.7316 10.2114 10.4712 10.4717C10.2109 10.7321 9.78878 10.7321 9.52843 10.4717L7.99984 8.94313L6.47124 10.4717C6.21089 10.7321 5.78878 10.7321 5.52843 10.4717C5.26808 10.2114 5.26808 9.78927 5.52843 9.52892L7.05703 8.00033L5.52843 6.47173C5.26808 6.21138 5.26808 5.78927 5.52843 5.52892C5.78878 5.26857 6.21089 5.26857 6.47124 5.52892L7.99984 7.05752L9.52843 5.52892C9.78878 5.26857 10.2109 5.26857 10.4712 5.52892Z"
fill={color}
/>
</IconWrapper>
);
};
+2
View File
@@ -17,3 +17,5 @@ export * from "./activity-icon";
export * from "./info-icon";
export * from "./updates-icon";
export * from "./shift-icon";
export * from "./check-circle-filled-icon";
export * from "./close-circle-filled-icon";