diff --git a/plane-src/apps/web/ce/components/projects/external-contours/actions-menu.tsx b/plane-src/apps/web/ce/components/projects/external-contours/actions-menu.tsx
index 2cf098b..ee21468 100644
--- a/plane-src/apps/web/ce/components/projects/external-contours/actions-menu.tsx
+++ b/plane-src/apps/web/ce/components/projects/external-contours/actions-menu.tsx
@@ -8,7 +8,8 @@ import { MoreHorizontal, Bell, BellOff } from "lucide-react";
import { useTranslation } from "@plane/i18n";
import { getIconButtonStyling } from "@plane/propel/icon-button";
import { CheckCircleFilledIcon, CloseCircleFilledIcon, CopyLinkIcon, NewTabIcon } from "@plane/propel/icons";
-import { CustomMenu } from "@plane/ui";
+import type { TContextMenuItem } from "@plane/ui";
+import { ActionDropdown } from "@plane/ui";
type Props = {
canOpenTargetWorkItem: boolean;
@@ -38,54 +39,70 @@ export const ExternalContourActionsMenu = (props: Props) => {
} = props;
const { t } = useTranslation();
- return (
- }
- customButtonClassName={getIconButtonStyling("secondary", "lg")}
- placement="bottom-start"
- >
- {includeDecisionActions && canReviewClosedRequest && onAccept && (
-
-
-
- {t("external_contours_page.actions.accept")}
-
-
- )}
-
- {includeDecisionActions && canReviewClosedRequest && onDecline && (
-
-
-
- {t("external_contours_page.actions.decline")}
-
-
- )}
-
-
+ const items: TContextMenuItem[] = [
+ {
+ key: "accept",
+ action: () => onAccept?.(),
+ shouldRender: includeDecisionActions && canReviewClosedRequest && !!onAccept,
+ customContent: (
+
+
+ {t("external_contours_page.actions.accept")}
+
+ ),
+ },
+ {
+ key: "decline",
+ action: () => onDecline?.(),
+ shouldRender: includeDecisionActions && canReviewClosedRequest && !!onDecline,
+ customContent: (
+
+
+ {t("external_contours_page.actions.decline")}
+
+ ),
+ },
+ {
+ key: "copy",
+ action: onCopy,
+ customContent: (
{t("external_contours_page.actions.copy")}
-
+ ),
+ },
+ {
+ key: "open",
+ action: () => onOpenTarget?.(),
+ shouldRender: canOpenTargetWorkItem && !!onOpenTarget,
+ customContent: (
+
+
+ {t("external_contours_page.actions.open")}
+
+ ),
+ },
+ {
+ key: "toggle-subscription",
+ action: () => onToggleSubscription?.(),
+ shouldRender: canOpenTargetWorkItem && !!onToggleSubscription,
+ disabled: isSubscriptionLoading || isSubscribed === undefined,
+ customContent: (
+
+ {isSubscribed ? : }
+ {isSubscribed ? t("common.actions.unsubscribe") : t("common.actions.subscribe")}
+
+ ),
+ },
+ ];
- {canOpenTargetWorkItem && onOpenTarget && (
-
-
-
- {t("external_contours_page.actions.open")}
-
-
- )}
-
- {canOpenTargetWorkItem && onToggleSubscription && (
-
-
- {isSubscribed ? : }
- {isSubscribed ? t("common.actions.unsubscribe") : t("common.actions.subscribe")}
-
-
- )}
-
+ return (
+ }
+ buttonClassName={getIconButtonStyling("secondary", "lg")}
+ placement="bottom-start"
+ />
);
};
diff --git a/plane-src/apps/web/core/components/cycles/quick-actions.tsx b/plane-src/apps/web/core/components/cycles/quick-actions.tsx
index 0c4e8be..c2ef6fa 100644
--- a/plane-src/apps/web/core/components/cycles/quick-actions.tsx
+++ b/plane-src/apps/web/core/components/cycles/quick-actions.tsx
@@ -10,10 +10,10 @@ import { MoreHorizontal } from "lucide-react";
// ui
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
import { useTranslation } from "@plane/i18n";
-import { IconButton } from "@plane/propel/icon-button";
+import { getIconButtonStyling } from "@plane/propel/icon-button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { TContextMenuItem } from "@plane/ui";
-import { ContextMenu, CustomMenu } from "@plane/ui";
+import { ActionDropdown, ContextMenu } from "@plane/ui";
import { copyUrlToClipboard, cn } from "@plane/utils";
// hooks
import { useCycleMenuItems } from "@/components/common/quick-actions-helper";
@@ -101,15 +101,6 @@ export const CycleQuickActions = observer(function CycleQuickActions(props: Prop
const MENU_ITEMS: TContextMenuItem[] = Array.isArray(menuResult) ? menuResult : menuResult.items;
const additionalModals = Array.isArray(menuResult) ? null : menuResult.modals;
- const CONTEXT_MENU_ITEMS = MENU_ITEMS.map(function CONTEXT_MENU_ITEMS(item) {
- return {
- ...item,
- action: () => {
- item.action();
- },
- };
- });
-
return (
<>
{cycleDetails && (
@@ -138,48 +129,13 @@ export const CycleQuickActions = observer(function CycleQuickActions(props: Prop
{additionalModals}
)}
-
- }
+
+ }
placement="bottom-end"
- closeOnSelect
- maxHeight="lg"
- buttonClassName={customClassName}
- >
- {MENU_ITEMS.map((item) => {
- if (item.shouldRender === false) return null;
- return (
- {
- item.action();
- }}
- className={cn(
- "flex items-center gap-2",
- {
- "text-placeholder": item.disabled,
- },
- item.className
- )}
- disabled={item.disabled}
- >
- {item.icon && }
-
-
{item.title}
- {item.description && (
-
- {item.description}
-
- )}
-
-
- );
- })}
-
+ buttonClassName={cn(getIconButtonStyling("tertiary", "lg"), customClassName)}
+ />
>
);
});
diff --git a/plane-src/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/helper.tsx b/plane-src/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/helper.tsx
index 3c19633..a7f33ba 100644
--- a/plane-src/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/helper.tsx
+++ b/plane-src/apps/web/core/components/issues/issue-layouts/quick-action-dropdowns/helper.tsx
@@ -4,7 +4,6 @@
* See the LICENSE file for details.
*/
-import type { ReactNode } from "react";
import { useMemo } from "react";
import { XCircle, ArchiveRestoreIcon } from "lucide-react";
// plane imports
@@ -12,8 +11,7 @@ import { useTranslation } from "@plane/i18n";
import { LinkIcon, CopyIcon, NewTabIcon, EditIcon, ArchiveIcon, TrashIcon } from "@plane/propel/icons";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { EIssuesStoreType, TIssue } from "@plane/types";
-import { CustomMenu, type TContextMenuItem } from "@plane/ui";
-import { cn } from "@plane/utils";
+import type { TContextMenuItem } from "@plane/ui";
import { copyUrlToClipboard, generateWorkItemLink } from "@plane/utils";
// types
import { createCopyMenuWithDuplication } from "@/plane-web/components/issues/issue-layouts/quick-action-dropdowns";
@@ -82,68 +80,6 @@ export interface MenuItemFactoryProps {
storeType?: EIssuesStoreType;
}
-export const QUICK_ACTION_MENU_LAYER_CLASS_NAME = "z-[220]";
-
-const renderQuickActionMenuItemContent = (item: TContextMenuItem) =>
- item.customContent ?? (
-
- {item.icon &&
}
-
- {item.title &&
{item.title}
}
- {item.description && (
-
- {item.description}
-
- )}
-
-
- );
-
-export const renderQuickActionMenuItems = (items: TContextMenuItem[]): ReactNode[] =>
- items.map((item) => {
- if (item.shouldRender === false) return null;
-
- if (item.nestedMenuItems?.some((nestedItem) => nestedItem.shouldRender !== false)) {
- return (
-
- {renderQuickActionMenuItems(item.nestedMenuItems)}
-
- );
- }
-
- return (
- item.action()}
- className={cn(
- "flex items-center gap-2",
- {
- "text-placeholder": item.disabled,
- },
- item.className
- )}
- disabled={item.disabled}
- >
- {renderQuickActionMenuItemContent(item)}
-
- );
- });
-
// Common action handlers hook
export const useIssueActionHandlers = (props: MenuItemFactoryProps) => {
const { issue, workspaceSlug, projectIdentifier, handleRestore } = props;
diff --git a/plane-src/apps/web/core/components/issues/layout-quick-actions.tsx b/plane-src/apps/web/core/components/issues/layout-quick-actions.tsx
index c68f9e9..22cf806 100644
--- a/plane-src/apps/web/core/components/issues/layout-quick-actions.tsx
+++ b/plane-src/apps/web/core/components/issues/layout-quick-actions.tsx
@@ -5,13 +5,13 @@
*/
import { observer } from "mobx-react";
-import { TOAST_TYPE, setToast } from "@plane/propel/toast";
-import type { TContextMenuItem } from "@plane/ui";
-import { CustomMenu } from "@plane/ui";
-import { copyUrlToClipboard, cn } from "@plane/utils";
-import { useLayoutMenuItems } from "@/components/common/quick-actions-helper";
import { Ellipsis } from "lucide-react";
-import { IconButton } from "@plane/propel/icon-button";
+import { TOAST_TYPE, setToast } from "@plane/propel/toast";
+import { getIconButtonStyling } from "@plane/propel/icon-button";
+import type { TContextMenuItem } from "@plane/ui";
+import { ActionDropdown } from "@plane/ui";
+import { copyUrlToClipboard } from "@plane/utils";
+import { useLayoutMenuItems } from "@/components/common/quick-actions-helper";
type Props = {
workspaceSlug: string;
@@ -49,31 +49,12 @@ export const LayoutQuickActions = observer(function LayoutQuickActions(props: Pr
return (
<>
{additionalModals}
- }
- >
- {MENU_ITEMS.map((item) => {
- if (item.shouldRender === false) return null;
- return (
-
- {item.icon && }
- {item.title}
-
- );
- })}
-
+ button={}
+ buttonClassName={getIconButtonStyling("tertiary", "lg")}
+ />
>
);
});
diff --git a/plane-src/apps/web/core/components/modules/quick-actions.tsx b/plane-src/apps/web/core/components/modules/quick-actions.tsx
index f62e5cc..6d6012e 100644
--- a/plane-src/apps/web/core/components/modules/quick-actions.tsx
+++ b/plane-src/apps/web/core/components/modules/quick-actions.tsx
@@ -9,10 +9,10 @@ import { observer } from "mobx-react";
import { MoreHorizontal } from "lucide-react";
// plane imports
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
-import { IconButton } from "@plane/propel/icon-button";
+import { getIconButtonStyling } from "@plane/propel/icon-button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { TContextMenuItem } from "@plane/ui";
-import { ContextMenu, CustomMenu } from "@plane/ui";
+import { ActionDropdown, ContextMenu } from "@plane/ui";
import { copyUrlToClipboard, cn } from "@plane/utils";
// components
import { useModuleMenuItems } from "@/components/common/quick-actions-helper";
@@ -101,16 +101,6 @@ export const ModuleQuickActions = observer(function ModuleQuickActions(props: Pr
const MENU_ITEMS: TContextMenuItem[] = Array.isArray(menuResult) ? menuResult : menuResult.items;
const additionalModals = Array.isArray(menuResult) ? null : menuResult.modals;
- const CONTEXT_MENU_ITEMS = MENU_ITEMS.map(function CONTEXT_MENU_ITEMS(item) {
- return {
- ...item,
-
- onClick: () => {
- item.action();
- },
- };
- });
-
return (
<>
{moduleDetails && (
@@ -133,47 +123,13 @@ export const ModuleQuickActions = observer(function ModuleQuickActions(props: Pr
{additionalModals}
)}
-
- }
+
+ }
placement="bottom-end"
- closeOnSelect
- buttonClassName={customClassName}
- >
- {MENU_ITEMS.map((item) => {
- if (item.shouldRender === false) return null;
- return (
- {
- item.action();
- }}
- className={cn(
- "flex items-center gap-2",
- {
- "text-placeholder": item.disabled,
- },
- item.className
- )}
- disabled={item.disabled}
- >
- {item.icon && }
-
-
{item.title}
- {item.description && (
-
- {item.description}
-
- )}
-
-
- );
- })}
-
+ buttonClassName={cn(getIconButtonStyling("tertiary", "lg"), customClassName)}
+ />
>
);
});
diff --git a/plane-src/apps/web/core/components/pages/dropdowns/actions.tsx b/plane-src/apps/web/core/components/pages/dropdowns/actions.tsx
index aec992c..b4763c7 100644
--- a/plane-src/apps/web/core/components/pages/dropdowns/actions.tsx
+++ b/plane-src/apps/web/core/components/pages/dropdowns/actions.tsx
@@ -7,16 +7,15 @@
import { useMemo, useState } from "react";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
-import { ArchiveRestoreIcon, FileOutput, LockKeyhole, LockKeyholeOpen } from "lucide-react";
+import { ArchiveRestoreIcon, FileOutput, LockKeyhole, LockKeyholeOpen, MoreHorizontal } from "lucide-react";
// constants
import { EPageAccess } from "@plane/constants";
// plane editor
import { LinkIcon, CopyIcon, LockIcon, NewTabIcon, ArchiveIcon, TrashIcon, GlobeIcon } from "@plane/propel/icons";
+import { getIconButtonStyling } from "@plane/propel/icon-button";
// plane ui
import type { TContextMenuItem } from "@plane/ui";
-import { ContextMenu, CustomMenu } from "@plane/ui";
-// components
-import { cn } from "@plane/utils";
+import { ActionDropdown, ContextMenu } from "@plane/ui";
import { DeletePageModal } from "@/components/pages/modals/delete-page-modal";
// hooks
import { usePageOperations } from "@/hooks/use-page-operations";
@@ -188,28 +187,12 @@ export const PageActions = observer(function PageActions(props: Props) {
storeType={storeType}
/>
{parentRef && }
-
- {arrangedOptions.map((item) => {
- if (item.shouldRender === false) return null;
- return (
- {
- item.action?.();
- }}
- className={cn("flex items-center gap-2", item.className)}
- disabled={item.disabled}
- >
- {item.customContent ?? (
- <>
- {item.icon && }
- {item.title}
- >
- )}
-
- );
- })}
-
+ }
+ buttonClassName={getIconButtonStyling("tertiary", "lg")}
+ />
>
);
});
diff --git a/plane-src/apps/web/core/components/views/quick-actions.tsx b/plane-src/apps/web/core/components/views/quick-actions.tsx
index ea85af9..efecee3 100644
--- a/plane-src/apps/web/core/components/views/quick-actions.tsx
+++ b/plane-src/apps/web/core/components/views/quick-actions.tsx
@@ -9,12 +9,12 @@ import { observer } from "mobx-react";
import { MoreHorizontal } from "lucide-react";
// types
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
-import { IconButton } from "@plane/propel/icon-button";
+import { getIconButtonStyling } from "@plane/propel/icon-button";
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
import type { IProjectView } from "@plane/types";
// ui
import type { TContextMenuItem } from "@plane/ui";
-import { ContextMenu, CustomMenu } from "@plane/ui";
+import { ActionDropdown, ContextMenu } from "@plane/ui";
import { copyUrlToClipboard, cn } from "@plane/utils";
// helpers
import { useViewMenuItems } from "@/components/common/quick-actions-helper";
@@ -79,15 +79,6 @@ export const ViewQuickActions = observer(function ViewQuickActions(props: Props)
if (publishContextMenu) MENU_ITEMS.splice(2, 0, publishContextMenu);
- const CONTEXT_MENU_ITEMS = MENU_ITEMS.map(function CONTEXT_MENU_ITEMS(item) {
- return {
- ...item,
- action: () => {
- item.action();
- },
- };
- });
-
return (
<>
setDeleteViewModal(false)} />
setPublishModalOpen(false)} view={view} />
{additionalModals}
-
- }
+
+ }
placement="bottom-end"
- closeOnSelect
- buttonClassName={customClassName}
- >
- {MENU_ITEMS.map((item) => {
- if (item.shouldRender === false) return null;
- return (
- {
- item.action();
- }}
- className={cn(
- "flex items-center gap-2",
- {
- "text-placeholder": item.disabled,
- },
- item.className
- )}
- disabled={item.disabled}
- >
- {item.icon && }
-
-
{item.title}
- {item.description && (
-
- {item.description}
-
- )}
-
-
- );
- })}
-
+ buttonClassName={cn(getIconButtonStyling("tertiary", "lg"), customClassName)}
+ />
>
);
});