Delete and Update History
This commit is contained in:
parent
1c980c4059
commit
f87953ba5c
@ -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",
|
||||
|
@ -9,7 +9,6 @@ export const SettingsOllama = () => {
|
||||
queryKey: ["fetchOllamURL"],
|
||||
queryFn: async () => {
|
||||
const ollamaURL = await getOllamaURL()
|
||||
|
||||
return {
|
||||
ollamaURL
|
||||
}
|
||||
|
@ -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<string>("")
|
||||
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 (
|
||||
<div className="overflow-y-auto">
|
||||
<div className="overflow-y-auto z-99">
|
||||
{status === "success" && chatHistories.length === 0 && (
|
||||
<div className="flex justify-center items-center mt-20 overflow-hidden">
|
||||
<Empty description="No history yet" />
|
||||
@ -41,18 +78,49 @@ export const Sidebar = ({}: Props) => {
|
||||
{status === "success" && chatHistories.length > 0 && (
|
||||
<div className="flex flex-col gap-2">
|
||||
{chatHistories.map((chat, index) => (
|
||||
<button
|
||||
onClick={async () => {
|
||||
const db = new PageAssitDatabase()
|
||||
const history = await db.getChatHistory(chat.id)
|
||||
setHistoryId(chat.id)
|
||||
setHistory(formatToChatHistory(history))
|
||||
setMessages(formatToMessage(history))
|
||||
}}
|
||||
<div
|
||||
key={index}
|
||||
className="flex text-start py-2 px-2 cursor-pointer 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">
|
||||
<span className="flex-grow truncate">{chat.title}</span>
|
||||
</button>
|
||||
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">
|
||||
<button
|
||||
className="flex-1 overflow-hidden break-all text-start truncate w-full"
|
||||
onClick={async () => {
|
||||
const db = new PageAssitDatabase()
|
||||
const history = await db.getChatHistory(chat.id)
|
||||
setHistoryId(chat.id)
|
||||
setHistory(formatToChatHistory(history))
|
||||
setMessages(formatToMessage(history))
|
||||
}}>
|
||||
<span className="flex-grow truncate">{chat.title}</span>
|
||||
</button>
|
||||
<div className="flex flex-row gap-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
const newTitle = prompt("Enter new title", chat.title)
|
||||
|
||||
if (newTitle) {
|
||||
editHistory({ id: chat.id, title: newTitle })
|
||||
}
|
||||
|
||||
setProcessingId(chat.id)
|
||||
}}
|
||||
className="text-gray-500 dark:text-gray-400 opacity-80">
|
||||
<PencilIcon className="w-4 h-4" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
if (
|
||||
!confirm("Are you sure you want to delete this history?")
|
||||
)
|
||||
return
|
||||
deleteHistory(chat.id)
|
||||
setProcessingId(chat.id)
|
||||
}}
|
||||
className="text-red-500 dark:text-red-400 opacity-80">
|
||||
<Trash className=" w-4 h-4 " />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
20
src/icons/EllipsisHorizontalIcon.tsx
Normal file
20
src/icons/EllipsisHorizontalIcon.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
type Props = {
|
||||
className: string
|
||||
}
|
||||
|
||||
export const EllipsisHorizontalIcon = ({ className }: Props) => {
|
||||
return <svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
className={className}
|
||||
>
|
||||
<circle cx="12" cy="12" r="1"></circle>
|
||||
<circle cx="12" cy="5" r="1"></circle>
|
||||
<circle cx="12" cy="19" r="1"></circle>
|
||||
</svg>
|
||||
}
|
19
src/icons/PencilIcon.tsx
Normal file
19
src/icons/PencilIcon.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
type Props = {
|
||||
className: string
|
||||
}
|
||||
|
||||
export const PencilIcon = ({ className }: Props) => {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
viewBox="0 0 24 24"
|
||||
className={className}>
|
||||
<path d="M17 3a2.85 2.83 0 114 4L7.5 20.5 2 22l1.5-5.5zM15 5l4 4"></path>
|
||||
</svg>
|
||||
)
|
||||
}
|
@ -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 })
|
||||
}
|
||||
|
25
yarn.lock
25
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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user