diff --git a/website/public/locales/en/common.json b/website/public/locales/en/common.json index f1783669..abc9fb21 100644 --- a/website/public/locales/en/common.json +++ b/website/public/locales/en/common.json @@ -2,14 +2,17 @@ "about": "About", "account_settings": "Account", "admin_dashboard": "Admin Dashboard", + "copied": "Copied", "connect": "Connect", "conversational": "Conversational AI for everyone.", + "dark_mode": "Dark Mode", "dashboard": "Dashboard", "delete": "Delete", "discord": "Discord", "docs": "Docs", "github": "GitHub", "legal": "Legal", + "light_mode": "Light Mode", "loading": "Loading...", "more_information": "More Information", "no": "No", @@ -17,9 +20,8 @@ "report_a_bug": "Report a Bug", "sign_in": "Sign In", "sign_out": "Sign Out", + "success": "Success", "terms_of_service": "Terms of Service", "title": "Open Assistant", - "yes": "Yes", - "dark_mode": "Dark Mode", - "light_mode": "Light Mode" + "yes": "Yes" } diff --git a/website/public/locales/en/message.json b/website/public/locales/en/message.json index ac9689a2..c65b1cfa 100644 --- a/website/public/locales/en/message.json +++ b/website/public/locales/en/message.json @@ -1,16 +1,20 @@ { + "copy_message_id": "Copy message ID", "label_action": "Label", "label_title": "Label", + "message_deleted": "Message deleted", "message": "Message", "open_new_tab_action": "Open in new tab", "parent": "Parent", "reactions": "Reactions", + "recent_messages": "Recent Messages", "report_action": "Report", "report_placeholder": "Why should this message be reviewed?", "report_title": "Report", "send_report": "Send", + "stop_tree": "Stop tree", "submit_labels": "Submit", + "tree_stopped": "Tree stopped {{id}}", "view_user": "View user", - "recent_messages": "Recent Messages", "your_recent_messages": "Your Recent Messages" } diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index cec724e5..3fb8d59a 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -12,9 +12,10 @@ import { useBreakpointValue, useColorModeValue, useDisclosure, + useToast, } from "@chakra-ui/react"; import { boolean } from "boolean"; -import { ClipboardList, Flag, MessageSquare, MoreHorizontal, Trash, User } from "lucide-react"; +import { ClipboardList, Copy, Flag, MessageSquare, MoreHorizontal, Slash, Trash, User } from "lucide-react"; import { useRouter } from "next/router"; import { useSession } from "next-auth/react"; import { useTranslation } from "next-i18next"; @@ -22,7 +23,7 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { LabelMessagePopup } from "src/components/Messages/LabelPopup"; import { MessageEmojiButton } from "src/components/Messages/MessageEmojiButton"; import { ReportPopup } from "src/components/Messages/ReportPopup"; -import { del, post } from "src/lib/api"; +import { del, post, put } from "src/lib/api"; import { colors } from "src/styles/Theme/colors"; import { Message, MessageEmojis } from "src/types/Conversation"; import { emojiIcons, isKnownEmoji } from "src/types/Emoji"; @@ -142,6 +143,8 @@ const EmojiMenuItem = ({ ); }; +const CHAR_COUNT = 10; + const MessageActions = ({ react, userEmoji, @@ -155,16 +158,47 @@ const MessageActions = ({ onReport: () => void; message: Message; }) => { + const toast = useToast(); const { t } = useTranslation(["message", "common"]); - const { trigger } = useSWRMutation(`/api/admin/delete_message/${message.id}`, del); - const { data } = useSession() || {}; - const role = data?.user?.role; + const id = message.id; + const displayId = id.slice(0, CHAR_COUNT) + "..." + id.slice(-CHAR_COUNT); + const { trigger: deleteMessage } = useSWRMutation(`/api/admin/delete_message/${message.id}`, del); + + const { trigger: stopTree } = useSWRMutation(`/api/admin/stop_tree/${message.id}`, put, { + onSuccess: () => { + toast({ + title: t("common:success"), + description: t("tree_stopped", { id: displayId }), + status: "success", + duration: 5000, + isClosable: true, + }); + }, + }); + + const { data: session } = useSession(); + const isAdmin = session?.user?.role === "admin"; const handleDelete = async () => { - await trigger(); + await deleteMessage(); mutate((key) => typeof key === "string" && key.startsWith("/api/messages"), undefined, { revalidate: true }); }; + const handleStop = () => { + stopTree(); + }; + + const handleCopyId = () => { + navigator.clipboard.writeText(message.id); + toast({ + title: t("common:copied"), + description: displayId, + status: "info", + duration: 5000, + isClosable: true, + }); + }; + return (