From f87953ba5c39be9f8659d78fa1d58b199c6f9233 Mon Sep 17 00:00:00 2001 From: n4ze3m Date: Sat, 24 Feb 2024 00:39:50 +0530 Subject: [PATCH] Delete and Update History --- package.json | 1 + src/components/Option/Settings/ollama.tsx | 1 - src/components/Option/Sidebar.tsx | 100 ++++++++++++++++++---- src/icons/EllipsisHorizontalIcon.tsx | 20 +++++ src/icons/PencilIcon.tsx | 19 ++++ src/libs/db.ts | 23 +++++ yarn.lock | 25 ++++++ 7 files changed, 172 insertions(+), 17 deletions(-) create mode 100644 src/icons/EllipsisHorizontalIcon.tsx create mode 100644 src/icons/PencilIcon.tsx diff --git a/package.json b/package.json index 9a8109f..df967fb 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@ant-design/cssinjs": "^1.18.4", + "@headlessui/react": "^1.7.18", "@heroicons/react": "^2.1.1", "@langchain/community": "^0.0.21", "@langchain/core": "^0.1.22", diff --git a/src/components/Option/Settings/ollama.tsx b/src/components/Option/Settings/ollama.tsx index 361e2a0..404a3eb 100644 --- a/src/components/Option/Settings/ollama.tsx +++ b/src/components/Option/Settings/ollama.tsx @@ -9,7 +9,6 @@ export const SettingsOllama = () => { queryKey: ["fetchOllamURL"], queryFn: async () => { const ollamaURL = await getOllamaURL() - return { ollamaURL } diff --git a/src/components/Option/Sidebar.tsx b/src/components/Option/Sidebar.tsx index 650d8f2..cadd882 100644 --- a/src/components/Option/Sidebar.tsx +++ b/src/components/Option/Sidebar.tsx @@ -1,16 +1,26 @@ -import { useQuery } from "@tanstack/react-query" +import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" import { PageAssitDatabase, formatToChatHistory, - formatToMessage + formatToMessage, + deleteByHistoryId, + updateHistory } from "~libs/db" -import { Empty, Skeleton } from "antd" +import { Dropdown, Empty, Skeleton, Spin } from "antd" import { useMessageOption } from "~hooks/useMessageOption" +import { Trash } from "~icons/Trash" +import { Fragment, useState } from "react" +import { PencilIcon } from "~icons/PencilIcon" +import { EllipsisHorizontalIcon } from "~icons/EllipsisHorizontalIcon" +import { Menu, Transition } from "@headlessui/react" type Props = {} export const Sidebar = ({}: Props) => { - const { setMessages, setHistory, setHistoryId } = useMessageOption() + const { setMessages, setHistory, setHistoryId, historyId, clearChat } = + useMessageOption() + const [processingId, setProcessingId] = useState("") + const client = useQueryClient() const { data: chatHistories, status } = useQuery({ queryKey: ["fetchChatHistory"], @@ -21,8 +31,35 @@ export const Sidebar = ({}: Props) => { } }) + const { isPending: isDeleting, mutate: deleteHistory } = useMutation({ + mutationKey: ["deleteHistory"], + mutationFn: deleteByHistoryId, + onSuccess: (history_id) => { + client.invalidateQueries({ + queryKey: ["fetchChatHistory"] + }) + setProcessingId("") + if (historyId === history_id) { + clearChat() + } + } + }) + + const { isPending: isEditing, mutate: editHistory } = useMutation({ + mutationKey: ["editHistory"], + mutationFn: async (data: { id: string; title: string }) => { + return await updateHistory(data.id, data.title) + }, + onSuccess: () => { + client.invalidateQueries({ + queryKey: ["fetchChatHistory"] + }) + setProcessingId("") + } + }) + return ( -
+
{status === "success" && chatHistories.length === 0 && (
@@ -41,18 +78,49 @@ export const Sidebar = ({}: Props) => { {status === "success" && chatHistories.length > 0 && (
{chatHistories.map((chat, index) => ( - + className="flex py-2 px-2 items-start gap-3 relative rounded-md truncate hover:pr-4 group transition-opacity duration-300 ease-in-out bg-gray-100 dark:bg-[#232222] dark:text-gray-100 text-gray-800 border hover:bg-gray-200 dark:hover:bg-[#2d2d2d] dark:border-gray-800"> + +
+ + + +
+
))}
)} diff --git a/src/icons/EllipsisHorizontalIcon.tsx b/src/icons/EllipsisHorizontalIcon.tsx new file mode 100644 index 0000000..7d44a59 --- /dev/null +++ b/src/icons/EllipsisHorizontalIcon.tsx @@ -0,0 +1,20 @@ +type Props = { + className: string +} + +export const EllipsisHorizontalIcon = ({ className }: Props) => { + return + + + + +} \ No newline at end of file diff --git a/src/icons/PencilIcon.tsx b/src/icons/PencilIcon.tsx new file mode 100644 index 0000000..9f9df61 --- /dev/null +++ b/src/icons/PencilIcon.tsx @@ -0,0 +1,19 @@ +type Props = { + className: string +} + +export const PencilIcon = ({ className }: Props) => { + return ( + + + + ) +} diff --git a/src/libs/db.ts b/src/libs/db.ts index f7a9037..ad1bc4a 100644 --- a/src/libs/db.ts +++ b/src/libs/db.ts @@ -87,6 +87,10 @@ export class PageAssitDatabase { } this.db.remove("chatHistories") } + + async deleteMessage(history_id: string) { + await this.db.remove(history_id) + } } const generateID = () => { @@ -145,3 +149,22 @@ export const formatToMessage = (messages: MessageHistory): MessageType[] => { } }) } + +export const deleteByHistoryId = async (history_id: string) => { + const db = new PageAssitDatabase() + await db.deleteMessage(history_id) + await db.removeChatHistory(history_id) + return history_id +} + +export const updateHistory = async (id: string, title: string) => { + const db = new PageAssitDatabase() + const chatHistories = await db.getChatHistories() + const newChatHistories = chatHistories.map((history) => { + if (history.id === id) { + history.title = title + } + return history + }) + db.db.set({ chatHistories: newChatHistories }) +} diff --git a/yarn.lock b/yarn.lock index e09349e..1071dd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -456,6 +456,14 @@ dependencies: cross-spawn "^7.0.3" +"@headlessui/react@^1.7.18": + version "1.7.18" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.18.tgz#30af4634d2215b2ca1aa29d07f33d02bea82d9d7" + integrity sha512-4i5DOrzwN4qSgNsL4Si61VMkUcWbcSKueUV7sFhpHzQcSShdlHENE5+QBntMSRvHt8NyoFO2AGG8si9lq+w4zQ== + dependencies: + "@tanstack/react-virtual" "^3.0.0-beta.60" + client-only "^0.0.1" + "@heroicons/react@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-2.1.1.tgz#422deb80c4d6caf3371aec6f4bee8361a354dc13" @@ -2306,6 +2314,18 @@ dependencies: "@tanstack/query-core" "5.18.0" +"@tanstack/react-virtual@^3.0.0-beta.60": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.1.2.tgz#eb62b73cc82e34860604cd3d682a17db590f3c45" + integrity sha512-qibmxtctgOZo2I+3Rw5GR9kXgaa15U5r3/idDY1ItUKW15UK7GhCfyIfE6qYuJ1fxQF6dJDsD8SbpPyuJgpxuA== + dependencies: + "@tanstack/virtual-core" "3.1.2" + +"@tanstack/virtual-core@3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.1.2.tgz#ca76f28f826fbd3310f88c3cd355d9c4aba80abb" + integrity sha512-DATZJs8iejkIUqXZe6ruDAnjFo78BKnIIgqQZrc7CmEFqfLEN/TPD91n4hRfo6hpRB6xC00bwKxv7vdjFNEmOg== + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -3078,6 +3098,11 @@ cli-width@^4.1.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== +client-only@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"