From e9add425e607454241ff0ab9b273e534637741eb Mon Sep 17 00:00:00 2001 From: rjmacarthy Date: Tue, 31 Jan 2023 19:44:12 +0000 Subject: [PATCH] Add delete message feature Remove deleted property from Message Add dedicated route for delete_message Pre-commit Revert change to promp_repository fetch_message Remove blank line --- website/public/locales/en/common.json | 3 ++- .../components/Messages/MessageTableEntry.tsx | 17 ++++++++++++++--- website/src/lib/api.ts | 2 ++ website/src/lib/oasst_api_client.ts | 17 ++++++++++++++++- .../src/pages/api/admin/delete_message/[id].ts | 15 +++++++++++++++ 5 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 website/src/pages/api/admin/delete_message/[id].ts diff --git a/website/public/locales/en/common.json b/website/public/locales/en/common.json index 6298a32c..86540b2d 100644 --- a/website/public/locales/en/common.json +++ b/website/public/locales/en/common.json @@ -18,5 +18,6 @@ "sign_out": "Sign Out", "terms_of_service": "Terms of Service", "title": "Open Assistant", - "yes": "Yes" + "yes": "Yes", + "delete": "Delete" } diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index 63c90a33..63b1cf32 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -14,7 +14,7 @@ import { useDisclosure, } from "@chakra-ui/react"; import { boolean } from "boolean"; -import { ClipboardList, Flag, MessageSquare, MoreHorizontal, User } from "lucide-react"; +import { ClipboardList, Flag, MessageSquare, MoreHorizontal, Trash, User } from "lucide-react"; import { useRouter } from "next/router"; import { useSession } from "next-auth/react"; import { useTranslation } from "next-i18next"; @@ -22,9 +22,10 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { LabelMessagePopup } from "src/components/Messages/LabelPopup"; import { getEmojiIcon, MessageEmojiButton } from "src/components/Messages/MessageEmojiButton"; import { ReportPopup } from "src/components/Messages/ReportPopup"; -import { post } from "src/lib/api"; +import { del, post } from "src/lib/api"; import { colors } from "src/styles/Theme/colors"; import { Message, MessageEmojis } from "src/types/Conversation"; +import { mutate } from "swr"; import useSWRMutation from "swr/mutation"; interface MessageTableEntryProps { @@ -153,9 +154,16 @@ const MessageActions = ({ onReport: () => void; message: Message; }) => { - const { t } = useTranslation("message"); + const { t } = useTranslation(["message", "common"]); + const { trigger } = useSWRMutation(`/api/admin/delete_message/${message.id}`, del); const { data } = useSession() || {}; const role = data?.user?.role; + + const handleDelete = async () => { + await trigger(); + mutate((key) => typeof key === "string" && key.startsWith("/api/messages"), undefined, { revalidate: true }); + }; + return ( @@ -186,6 +194,9 @@ const MessageActions = ({ }> {t("view_user")} + }> + {t("common:delete")} + )} diff --git a/website/src/lib/api.ts b/website/src/lib/api.ts index bbb6d7e7..6c3bd900 100644 --- a/website/src/lib/api.ts +++ b/website/src/lib/api.ts @@ -17,6 +17,8 @@ export const get = (url: string) => api.get(url).then((res) => res.data); export const post = (url: string, { arg: data }) => api.post(url, data).then((res) => res.data); +export const del = (url: string) => api.delete(url).then((res) => res.data); + api.interceptors.response.use( (response) => response, (error) => { diff --git a/website/src/lib/oasst_api_client.ts b/website/src/lib/oasst_api_client.ts index 51e691b3..68428ae3 100644 --- a/website/src/lib/oasst_api_client.ts +++ b/website/src/lib/oasst_api_client.ts @@ -89,6 +89,13 @@ export class OasstApiClient { return this.get(`/api/v1/messages/${message_id}?username=${user.id}&auth_method=${user.auth_method}`); } + /** + * Delete a message by its id + */ + async delete_message(message_id: string): Promise { + return this.delete(`/api/v1/messages/${message_id}`); + } + /** * Send a report about a message */ @@ -202,6 +209,10 @@ export class OasstApiClient { return this.request("PUT", path); } + private async delete(path: string) { + return this.request("DELETE", path); + } + private async get(path: string, query?: Record) { if (!query) { return this.request("GET", path); @@ -216,7 +227,11 @@ export class OasstApiClient { return this.request("GET", `${path}?${params}`); } - private async request(method: "GET" | "POST" | "PUT", path: string, init?: RequestInit): Promise { + private async request( + method: "GET" | "POST" | "PUT" | "DELETE", + path: string, + init?: RequestInit + ): Promise { const resp = await fetch(`${this.oasstApiUrl}${path}`, { method, ...init, diff --git a/website/src/pages/api/admin/delete_message/[id].ts b/website/src/pages/api/admin/delete_message/[id].ts new file mode 100644 index 00000000..3dc607ed --- /dev/null +++ b/website/src/pages/api/admin/delete_message/[id].ts @@ -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.delete_message(id as string); + res.status(200).json({ message: "Message deleted" }); + } catch (e) { + res.status(500).json({ message: "Failed to delete message" }); + } +}); + +export default handler;