From 1fbf5dbd03a8a1a58db2192dc5d24e92b81db613 Mon Sep 17 00:00:00 2001 From: Aaryan Khandelwal <65252264+aaryan610@users.noreply.github.com> Date: Tue, 25 Jun 2024 18:26:35 +0530 Subject: [PATCH] [WEB-1559] fix: unable to delete pages (#491) * fix: pages not getting deleted * fix: dashboard page context menu click * fix: open in new tab --- .../components/pages/dashboard/list-item.tsx | 43 +++---- web/ee/components/pages/index.ts | 1 + .../pages/list/block-item-action.tsx | 6 +- .../pages/modals/delete-page-modal.tsx | 4 +- web/ee/components/pages/quick-actions.tsx | 116 ++++++++++++++++++ 5 files changed, 140 insertions(+), 30 deletions(-) create mode 100644 web/ee/components/pages/quick-actions.tsx diff --git a/web/ee/components/pages/dashboard/list-item.tsx b/web/ee/components/pages/dashboard/list-item.tsx index 8498d02ec4..dbbb7d3736 100644 --- a/web/ee/components/pages/dashboard/list-item.tsx +++ b/web/ee/components/pages/dashboard/list-item.tsx @@ -4,7 +4,8 @@ import { useParams } from "next/navigation"; import { FileText } from "lucide-react"; // components import { Logo } from "@/components/common"; -import { PageQuickActions } from "@/components/pages"; +// plane web components +import { WorkspacePageQuickActions } from "@/plane-web/components/pages"; // plane web hooks import { useWorkspacePageDetails } from "@/plane-web/hooks/store"; @@ -22,31 +23,23 @@ export const PagesAppDashboardListItem: React.FC = (props) => { const page = useWorkspacePageDetails(pageId); return ( - -
- - {page.logo_props?.in_use ? ( - - ) : ( - - )} - -

{page.name}

-
+
+ +
+ + {page.logo_props?.in_use ? ( + + ) : ( + + )} + +

{page.name}

+
+ {/* quick actions dropdown */} -
{ - e.preventDefault(); - e.stopPropagation(); - }} - > - +
+
- +
); }; diff --git a/web/ee/components/pages/index.ts b/web/ee/components/pages/index.ts index 3ccc13671b..4be770e5e8 100644 --- a/web/ee/components/pages/index.ts +++ b/web/ee/components/pages/index.ts @@ -4,3 +4,4 @@ export * from "./list"; export * from "./modals"; export * from "./sidebar"; export * from "./extra-actions"; +export * from "./quick-actions"; diff --git a/web/ee/components/pages/list/block-item-action.tsx b/web/ee/components/pages/list/block-item-action.tsx index 6298d1ce01..f3a72daf86 100644 --- a/web/ee/components/pages/list/block-item-action.tsx +++ b/web/ee/components/pages/list/block-item-action.tsx @@ -5,12 +5,12 @@ import { observer } from "mobx-react"; import { Earth, Info, Lock, Minus } from "lucide-react"; // ui import { Avatar, FavoriteStar, TOAST_TYPE, Tooltip, setToast } from "@plane/ui"; -// components -import { PageQuickActions } from "@/components/pages/dropdowns"; // helpers import { renderFormattedDate } from "@/helpers/date-time.helper"; // hooks import { useMember } from "@/hooks/store"; +// plane web components +import { WorkspacePageQuickActions } from "@/plane-web/components/pages"; // plane web hooks import { useWorkspacePageDetails } from "@/plane-web/hooks/store"; @@ -84,7 +84,7 @@ export const PageListBlockItemAction: FC = observer((props) => { /> {/* quick actions dropdown */} - + ); }); diff --git a/web/ee/components/pages/modals/delete-page-modal.tsx b/web/ee/components/pages/modals/delete-page-modal.tsx index abed701981..edb3b36e73 100644 --- a/web/ee/components/pages/modals/delete-page-modal.tsx +++ b/web/ee/components/pages/modals/delete-page-modal.tsx @@ -17,7 +17,7 @@ type TConfirmPageDeletionProps = { pageId: string; }; -export const PagesAppDeletePageModal: React.FC = observer((props) => { +export const WorkspacePageDeleteModal: React.FC = observer((props) => { const { pageId, isOpen, onClose } = props; // states const [isDeleting, setIsDeleting] = useState(false); @@ -77,7 +77,7 @@ export const PagesAppDeletePageModal: React.FC = obse handleSubmit={handleDelete} isSubmitting={isDeleting} isOpen={isOpen} - title="Delete Page" + title="Delete page" content={ <> Are you sure you want to delete page-{" "} diff --git a/web/ee/components/pages/quick-actions.tsx b/web/ee/components/pages/quick-actions.tsx new file mode 100644 index 0000000000..f00b51c0a4 --- /dev/null +++ b/web/ee/components/pages/quick-actions.tsx @@ -0,0 +1,116 @@ +"use client"; + +import { useState } from "react"; +import { observer } from "mobx-react"; +import { ArchiveRestoreIcon, ExternalLink, Link, Lock, Trash2, UsersRound } from "lucide-react"; +import { ArchiveIcon, ContextMenu, CustomMenu, TContextMenuItem, TOAST_TYPE, setToast } from "@plane/ui"; +// helpers +import { copyUrlToClipboard } from "@/helpers/string.helper"; +// plane web components +import { WorkspacePageDeleteModal } from "@/plane-web/components/pages"; +// store +import { IPage } from "@/store/pages/page"; + +type Props = { + page: IPage; + pageLink: string; + parentRef: React.RefObject; +}; + +export const WorkspacePageQuickActions: React.FC = observer((props) => { + const { page, pageLink, parentRef } = props; + // states + const [deletePageModal, setDeletePageModal] = useState(false); + // store hooks + const { + access, + archive, + archived_at, + makePublic, + makePrivate, + restore, + canCurrentUserArchivePage, + canCurrentUserChangeAccess, + canCurrentUserDeletePage, + } = page; + + const handleCopyText = () => + copyUrlToClipboard(pageLink).then(() => { + setToast({ + type: TOAST_TYPE.SUCCESS, + title: "Link Copied!", + message: "Page link copied to clipboard.", + }); + }); + + const handleOpenInNewTab = () => window.open(`/${pageLink}`, "_blank"); + + const MENU_ITEMS: TContextMenuItem[] = [ + { + key: "make-public-private", + action: access === 0 ? makePrivate : makePublic, + title: access === 0 ? "Make private" : "Make public", + icon: access === 0 ? Lock : UsersRound, + shouldRender: canCurrentUserChangeAccess && !archived_at, + }, + { + key: "open-new-tab", + action: handleOpenInNewTab, + title: "Open in new tab", + icon: ExternalLink, + shouldRender: true, + }, + { + key: "copy-link", + action: handleCopyText, + title: "Copy link", + icon: Link, + shouldRender: true, + }, + { + key: "archive-restore", + action: archived_at ? restore : archive, + title: archived_at ? "Restore" : "Archive", + icon: archived_at ? ArchiveRestoreIcon : ArchiveIcon, + shouldRender: canCurrentUserArchivePage, + }, + { + key: "delete", + action: () => setDeletePageModal(true), + title: "Delete", + icon: Trash2, + shouldRender: canCurrentUserDeletePage && !!archived_at, + }, + ]; + + return ( + <> + setDeletePageModal(false)} + pageId={page.id ?? ""} + /> + + + {MENU_ITEMS.map((item) => { + if (!item.shouldRender) return null; + return ( + { + e.preventDefault(); + e.stopPropagation(); + item.action(); + }} + className="flex items-center gap-2" + disabled={item.disabled} + > + {item.icon && } + {item.title} + + ); + })} + + + ); +});