From 7079790d4ff3bddc7f0b1ceb84492b064a1905f9 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Oct 2025 20:05:31 +0800 Subject: [PATCH] feat: add copy content functionality to MemoActionMenu --- web/src/components/MemoActionMenu.tsx | 37 +++++++++++++++++++++---- web/src/components/ui/dropdown-menu.tsx | 2 +- web/src/locales/en.json | 3 ++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/web/src/components/MemoActionMenu.tsx b/web/src/components/MemoActionMenu.tsx index a07401699..624721b84 100644 --- a/web/src/components/MemoActionMenu.tsx +++ b/web/src/components/MemoActionMenu.tsx @@ -6,6 +6,8 @@ import { BookmarkPlusIcon, CopyIcon, Edit3Icon, + FileTextIcon, + LinkIcon, MoreVerticalIcon, TrashIcon, SquareCheckIcon, @@ -24,7 +26,15 @@ import { NodeType } from "@/types/proto/api/v1/markdown_service"; import { Memo } from "@/types/proto/api/v1/memo_service"; import { useTranslate } from "@/utils/i18n"; import { Button } from "./ui/button"; -import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "./ui/dropdown-menu"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSub, + DropdownMenuSubContent, + DropdownMenuSubTrigger, + DropdownMenuTrigger, +} from "./ui/dropdown-menu"; interface Props { memo: Memo; @@ -127,6 +137,11 @@ const MemoActionMenu = observer((props: Props) => { toast.success(t("message.succeed-copy-link")); }; + const handleCopyContent = () => { + copy(memo.content); + toast.success(t("message.succeed-copy-content")); + }; + const handleDeleteMemoClick = () => { setDeleteDialogOpen(true); }; @@ -196,10 +211,22 @@ const MemoActionMenu = observer((props: Props) => { )} {!isArchived && ( - - - {t("memo.copy-link")} - + + + + {t("common.copy")} + + + + + {t("memo.copy-link")} + + + + {t("memo.copy-content")} + + + )} {!readonly && ( <> diff --git a/web/src/components/ui/dropdown-menu.tsx b/web/src/components/ui/dropdown-menu.tsx index d543c2973..0a724533b 100644 --- a/web/src/components/ui/dropdown-menu.tsx +++ b/web/src/components/ui/dropdown-menu.tsx @@ -176,7 +176,7 @@ function DropdownMenuSubTrigger({ data-slot="dropdown-menu-sub-trigger" data-inset={inset} className={cn( - "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8", + "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", className, )} {...props} diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 7f001d02e..0b8f6bf92 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -31,6 +31,7 @@ "close": "Close", "collapse": "Collapse", "confirm": "Confirm", + "copy": "Copy", "create": "Create", "created-at": "Created At", "database": "Database", @@ -141,6 +142,7 @@ "self": "Comments", "write-a-comment": "Write a comment" }, + "copy-content": "Copy Content", "copy-link": "Copy Link", "count-memos-in-date": "{{count}} {{memos}} in {{date}}", "delete-confirm": "Are you sure you want to delete this memo?", @@ -188,6 +190,7 @@ "password-not-match": "Passwords do not match.", "remove-completed-task-list-items-successfully": "The removal was successful", "restored-successfully": "Restored successfully", + "succeed-copy-content": "Content copied successfully.", "succeed-copy-link": "Link copied successfully.", "update-succeed": "Update succeeded", "user-not-found": "User not found"