mirror of
https://github.com/makeplane/plane.git
synced 2026-07-13 05:49:40 +02:00
[WEB-1559] fix: unable to delete pages (#491)
* fix: pages not getting deleted * fix: dashboard page context menu click * fix: open in new tab
This commit is contained in:
committed by
GitHub
parent
ada1dc0e60
commit
1fbf5dbd03
@@ -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> = (props) => {
|
||||
const page = useWorkspacePageDetails(pageId);
|
||||
|
||||
return (
|
||||
<Link
|
||||
href={`/${workspaceSlug.toString()}/pages/${pageId}`}
|
||||
className="group/list-item flex items-center justify-between gap-1.5 hover:bg-custom-background-90 py-1.5 px-1 rounded-md"
|
||||
ref={parentRef}
|
||||
>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="size-4 flex-shrink-0 grid place-items-center">
|
||||
{page.logo_props?.in_use ? (
|
||||
<Logo logo={page.logo_props} size={14} type="lucide" />
|
||||
) : (
|
||||
<FileText className="size-3.5 text-custom-text-300" />
|
||||
)}
|
||||
</span>
|
||||
<p className="text-custom-text-200 text-sm">{page.name}</p>
|
||||
</div>
|
||||
<div className="group/list-item rounded-md flex items-center gap-1.5 hover:bg-custom-background-90 py-1.5 px-1">
|
||||
<Link href={`/${workspaceSlug.toString()}/pages/${pageId}`} className="flex-grow" ref={parentRef}>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="size-4 flex-shrink-0 grid place-items-center">
|
||||
{page.logo_props?.in_use ? (
|
||||
<Logo logo={page.logo_props} size={14} type="lucide" />
|
||||
) : (
|
||||
<FileText className="size-3.5 text-custom-text-300" />
|
||||
)}
|
||||
</span>
|
||||
<p className="text-custom-text-200 text-sm">{page.name}</p>
|
||||
</div>
|
||||
</Link>
|
||||
{/* quick actions dropdown */}
|
||||
<div
|
||||
className="opacity-0 pointer-events-none group-hover/list-item:opacity-100 group-hover/list-item:pointer-events-auto"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
>
|
||||
<PageQuickActions parentRef={parentRef} page={page} pageLink={`/${workspaceSlug}/pages`} />
|
||||
<div className="opacity-0 pointer-events-none group-hover/list-item:opacity-100 group-hover/list-item:pointer-events-auto">
|
||||
<WorkspacePageQuickActions parentRef={parentRef} page={page} pageLink={`${workspaceSlug}/pages`} />
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -4,3 +4,4 @@ export * from "./list";
|
||||
export * from "./modals";
|
||||
export * from "./sidebar";
|
||||
export * from "./extra-actions";
|
||||
export * from "./quick-actions";
|
||||
|
||||
@@ -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<Props> = observer((props) => {
|
||||
/>
|
||||
|
||||
{/* quick actions dropdown */}
|
||||
<PageQuickActions parentRef={parentRef} page={page} pageLink={`${workspaceSlug}/pages/${pageId}`} />
|
||||
<WorkspacePageQuickActions parentRef={parentRef} page={page} pageLink={`${workspaceSlug}/pages/${pageId}`} />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ type TConfirmPageDeletionProps = {
|
||||
pageId: string;
|
||||
};
|
||||
|
||||
export const PagesAppDeletePageModal: React.FC<TConfirmPageDeletionProps> = observer((props) => {
|
||||
export const WorkspacePageDeleteModal: React.FC<TConfirmPageDeletionProps> = observer((props) => {
|
||||
const { pageId, isOpen, onClose } = props;
|
||||
// states
|
||||
const [isDeleting, setIsDeleting] = useState(false);
|
||||
@@ -77,7 +77,7 @@ export const PagesAppDeletePageModal: React.FC<TConfirmPageDeletionProps> = obse
|
||||
handleSubmit={handleDelete}
|
||||
isSubmitting={isDeleting}
|
||||
isOpen={isOpen}
|
||||
title="Delete Page"
|
||||
title="Delete page"
|
||||
content={
|
||||
<>
|
||||
Are you sure you want to delete page-{" "}
|
||||
|
||||
116
web/ee/components/pages/quick-actions.tsx
Normal file
116
web/ee/components/pages/quick-actions.tsx
Normal file
@@ -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<HTMLElement>;
|
||||
};
|
||||
|
||||
export const WorkspacePageQuickActions: React.FC<Props> = 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 (
|
||||
<>
|
||||
<WorkspacePageDeleteModal
|
||||
isOpen={deletePageModal}
|
||||
onClose={() => setDeletePageModal(false)}
|
||||
pageId={page.id ?? ""}
|
||||
/>
|
||||
<ContextMenu parentRef={parentRef} items={MENU_ITEMS} />
|
||||
<CustomMenu placement="bottom-end" ellipsis closeOnSelect>
|
||||
{MENU_ITEMS.map((item) => {
|
||||
if (!item.shouldRender) return null;
|
||||
return (
|
||||
<CustomMenu.MenuItem
|
||||
key={item.key}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
item.action();
|
||||
}}
|
||||
className="flex items-center gap-2"
|
||||
disabled={item.disabled}
|
||||
>
|
||||
{item.icon && <item.icon className="h-3 w-3" />}
|
||||
{item.title}
|
||||
</CustomMenu.MenuItem>
|
||||
);
|
||||
})}
|
||||
</CustomMenu>
|
||||
</>
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user