mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-06-29 16:30:24 +08:00
Add halt tree, and copy message id features (#1088)
This commit is contained in:
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<Menu>
|
||||
<MenuButton>
|
||||
@@ -189,15 +223,21 @@ const MessageActions = ({
|
||||
<MenuItem as="a" href={`/messages/${message.id}`} target="_blank" icon={<MessageSquare />}>
|
||||
{t("open_new_tab_action")}
|
||||
</MenuItem>
|
||||
{role === "admin" && (
|
||||
{!!isAdmin && (
|
||||
<>
|
||||
<MenuDivider />
|
||||
<MenuItem onClick={handleCopyId} icon={<Copy />}>
|
||||
{t("copy_message_id")}
|
||||
</MenuItem>
|
||||
<MenuItem as="a" href={`/admin/manage_user/${message.user_id}`} target="_blank" icon={<User />}>
|
||||
{t("view_user")}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleDelete} icon={<Trash />}>
|
||||
{t("common:delete")}
|
||||
</MenuItem>
|
||||
<MenuItem onClick={handleStop} icon={<Slash />}>
|
||||
{t("stop_tree")}
|
||||
</MenuItem>
|
||||
</>
|
||||
)}
|
||||
</MenuList>
|
||||
|
||||
@@ -19,6 +19,8 @@ export const post = (url: string, { arg: data }) => api.post(url, data).then((re
|
||||
|
||||
export const del = (url: string) => api.delete(url).then((res) => res.data);
|
||||
|
||||
export const put = (url: string, { arg: data }) => api.put(url, data).then((res) => res.data);
|
||||
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
|
||||
@@ -167,6 +167,13 @@ export class OasstApiClient {
|
||||
return this.delete<void>(`/api/v1/messages/${message_id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop message tree
|
||||
*/
|
||||
async stop_tree(message_id: string): Promise<void> {
|
||||
return this.put<void>(`/api/v1/messages/${message_id}/tree/state?halt=true`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a report about a message
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { withRole } from "src/lib/auth";
|
||||
import { createApiClient } from "src/lib/oasst_client_factory";
|
||||
|
||||
const handler = withRole("admin", async (req, res, token) => {
|
||||
const { id } = req.query;
|
||||
try {
|
||||
const client = await createApiClient(token);
|
||||
await client.stop_tree(id as string);
|
||||
res.status(200).json({ message: `Tree ${id} stopped`, id });
|
||||
} catch (e) {
|
||||
res.status(500).json(e);
|
||||
}
|
||||
});
|
||||
|
||||
export default handler;
|
||||
Reference in New Issue
Block a user