Delete all chats (#4171)

* nit

* k
This commit is contained in:
pablonyx
2025-03-04 10:00:08 -08:00
committed by GitHub
parent 61e8f371b9
commit ae585fd84c
6 changed files with 79 additions and 56 deletions

View File

@@ -1979,8 +1979,6 @@ export function ChatPage({
const innerSidebarElementRef = useRef<HTMLDivElement>(null); const innerSidebarElementRef = useRef<HTMLDivElement>(null);
const [settingsToggled, setSettingsToggled] = useState(false); const [settingsToggled, setSettingsToggled] = useState(false);
const [showDeleteAllModal, setShowDeleteAllModal] = useState(false);
const currentPersona = alternativeAssistant || liveAssistant; const currentPersona = alternativeAssistant || liveAssistant;
const HORIZON_DISTANCE = 800; const HORIZON_DISTANCE = 800;
@@ -2142,32 +2140,6 @@ export function ChatPage({
<ChatPopup /> <ChatPopup />
{showDeleteAllModal && (
<ConfirmEntityModal
entityType="All Chats"
entityName="all your chat sessions"
onClose={() => setShowDeleteAllModal(false)}
additionalDetails="This action cannot be undone. All your chat sessions will be deleted."
onSubmit={async () => {
const response = await deleteAllChatSessions("Chat");
if (response.ok) {
setShowDeleteAllModal(false);
setPopup({
message: "All your chat sessions have been deleted.",
type: "success",
});
refreshChatSessions();
router.push("/chat");
} else {
setPopup({
message: "Failed to delete all chat sessions.",
type: "error",
});
}
}}
/>
)}
{currentFeedback && ( {currentFeedback && (
<FeedbackModal <FeedbackModal
feedbackType={currentFeedback[0]} feedbackType={currentFeedback[0]}
@@ -2325,7 +2297,6 @@ export function ChatPage({
folders={folders} folders={folders}
removeToggle={removeToggle} removeToggle={removeToggle}
showShareModal={showShareModal} showShareModal={showShareModal}
showDeleteAllModal={() => setShowDeleteAllModal(true)}
/> />
</div> </div>

View File

@@ -329,7 +329,7 @@ export async function deleteChatSession(chatSessionId: string) {
return response; return response;
} }
export async function deleteAllChatSessions(sessionType: "Chat" | "Search") { export async function deleteAllChatSessions() {
const response = await fetch(`/api/chat/delete-all-chat-sessions`, { const response = await fetch(`/api/chat/delete-all-chat-sessions`, {
method: "DELETE", method: "DELETE",
headers: { headers: {

View File

@@ -24,6 +24,9 @@ import { Monitor, Moon, Sun } from "lucide-react";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input"; import { Input } from "@/components/ui/input";
import { FiTrash2 } from "react-icons/fi";
import { deleteAllChatSessions } from "../lib";
import { useChatContext } from "@/components/context/ChatContext";
type SettingsSection = "settings" | "password"; type SettingsSection = "settings" | "password";
@@ -47,6 +50,8 @@ export function UserSettingsModal({
updateUserShortcuts, updateUserShortcuts,
updateUserTemperatureOverrideEnabled, updateUserTemperatureOverrideEnabled,
} = useUser(); } = useUser();
const { refreshChatSessions } = useChatContext();
const router = useRouter();
const containerRef = useRef<HTMLDivElement>(null); const containerRef = useRef<HTMLDivElement>(null);
const messageRef = useRef<HTMLDivElement>(null); const messageRef = useRef<HTMLDivElement>(null);
const { theme, setTheme } = useTheme(); const { theme, setTheme } = useTheme();
@@ -57,6 +62,8 @@ export function UserSettingsModal({
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [activeSection, setActiveSection] = const [activeSection, setActiveSection] =
useState<SettingsSection>("settings"); useState<SettingsSection>("settings");
const [isDeleteAllLoading, setIsDeleteAllLoading] = useState(false);
const [showDeleteConfirmation, setShowDeleteConfirmation] = useState(false);
useEffect(() => { useEffect(() => {
const container = containerRef.current; const container = containerRef.current;
@@ -132,7 +139,6 @@ export function UserSettingsModal({
); );
}); });
const router = useRouter();
const handleChangedefaultModel = async (defaultModel: string | null) => { const handleChangedefaultModel = async (defaultModel: string | null) => {
try { try {
const response = await setUserDefaultModel(defaultModel); const response = await setUserDefaultModel(defaultModel);
@@ -205,6 +211,31 @@ export function UserSettingsModal({
}; };
const showPasswordSection = user?.password_configured; const showPasswordSection = user?.password_configured;
const handleDeleteAllChats = async () => {
setIsDeleteAllLoading(true);
try {
const response = await deleteAllChatSessions();
if (response.ok) {
setPopup({
message: "All your chat sessions have been deleted.",
type: "success",
});
refreshChatSessions();
router.push("/chat");
} else {
throw new Error("Failed to delete all chat sessions");
}
} catch (error) {
setPopup({
message: "Failed to delete all chat sessions",
type: "error",
});
} finally {
setIsDeleteAllLoading(false);
setShowDeleteConfirmation(false);
}
};
return ( return (
<Modal <Modal
onOutsideClick={onClose} onOutsideClick={onClose}
@@ -350,6 +381,51 @@ export function UserSettingsModal({
}} }}
/> />
</div> </div>
<div className="pt-4 border-t border-border">
{!showDeleteConfirmation ? (
<div className="space-y-3">
<p className="text-sm text-neutral-600 ">
This will permanently delete all your chat sessions and
cannot be undone.
</p>
<Button
variant="destructive"
className="w-full flex items-center justify-center"
onClick={() => setShowDeleteConfirmation(true)}
>
<FiTrash2 className="mr-2" size={14} />
Delete All Chats
</Button>
</div>
) : (
<div className="space-y-3">
<p className="text-sm text-neutral-600 ">
Are you sure you want to delete all your chat sessions?
</p>
<div className="flex gap-2">
<Button
type="button"
variant="destructive"
className="flex-1 flex items-center justify-center"
onClick={handleDeleteAllChats}
disabled={isDeleteAllLoading}
>
{isDeleteAllLoading
? "Deleting..."
: "Yes, Delete All"}
</Button>
<Button
variant="outline"
className="flex-1"
onClick={() => setShowDeleteConfirmation(false)}
disabled={isDeleteAllLoading}
>
Cancel
</Button>
</div>
</div>
)}
</div>
</div> </div>
)} )}
{activeSection === "password" && ( {activeSection === "password" && (

View File

@@ -64,7 +64,6 @@ interface HistorySidebarProps {
showShareModal?: (chatSession: ChatSession) => void; showShareModal?: (chatSession: ChatSession) => void;
showDeleteModal?: (chatSession: ChatSession) => void; showDeleteModal?: (chatSession: ChatSession) => void;
explicitlyUntoggle: () => void; explicitlyUntoggle: () => void;
showDeleteAllModal?: () => void;
setShowAssistantsModal: (show: boolean) => void; setShowAssistantsModal: (show: boolean) => void;
toggleChatSessionSearchModal?: () => void; toggleChatSessionSearchModal?: () => void;
} }
@@ -183,7 +182,6 @@ export const HistorySidebar = forwardRef<HTMLDivElement, HistorySidebarProps>(
showShareModal, showShareModal,
toggleChatSessionSearchModal, toggleChatSessionSearchModal,
showDeleteModal, showDeleteModal,
showDeleteAllModal,
}, },
ref: ForwardedRef<HTMLDivElement> ref: ForwardedRef<HTMLDivElement>
) => { ) => {
@@ -403,7 +401,6 @@ export const HistorySidebar = forwardRef<HTMLDivElement, HistorySidebarProps>(
existingChats={existingChats} existingChats={existingChats}
currentChatId={currentChatId} currentChatId={currentChatId}
folders={folders} folders={folders}
showDeleteAllModal={showDeleteAllModal}
/> />
</div> </div>
</div> </div>

View File

@@ -10,7 +10,6 @@ import { Folder } from "../folders/interfaces";
import { usePopup } from "@/components/admin/connectors/Popup"; import { usePopup } from "@/components/admin/connectors/Popup";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { FiPlus, FiTrash2, FiCheck, FiX } from "react-icons/fi"; import { FiPlus, FiTrash2, FiCheck, FiX } from "react-icons/fi";
import { NEXT_PUBLIC_DELETE_ALL_CHATS_ENABLED } from "@/lib/constants";
import { FolderDropdown } from "../folders/FolderDropdown"; import { FolderDropdown } from "../folders/FolderDropdown";
import { ChatSessionDisplay } from "./ChatSessionDisplay"; import { ChatSessionDisplay } from "./ChatSessionDisplay";
import { useState, useCallback, useRef, useContext, useEffect } from "react"; import { useState, useCallback, useRef, useContext, useEffect } from "react";
@@ -107,7 +106,6 @@ export function PagesTab({
closeSidebar, closeSidebar,
showShareModal, showShareModal,
showDeleteModal, showDeleteModal,
showDeleteAllModal,
toggleChatSessionSearchModal, toggleChatSessionSearchModal,
}: { }: {
existingChats?: ChatSession[]; existingChats?: ChatSession[];
@@ -117,7 +115,6 @@ export function PagesTab({
closeSidebar?: () => void; closeSidebar?: () => void;
showShareModal?: (chatSession: ChatSession) => void; showShareModal?: (chatSession: ChatSession) => void;
showDeleteModal?: (chatSession: ChatSession) => void; showDeleteModal?: (chatSession: ChatSession) => void;
showDeleteAllModal?: () => void;
}) { }) {
const { setPopup, popup } = usePopup(); const { setPopup, popup } = usePopup();
const router = useRouter(); const router = useRouter();
@@ -438,11 +435,7 @@ export function PagesTab({
</DndContext> </DndContext>
)} )}
<div <div className="pl-4 pr-3">
className={`pl-4 pr-3 ${
NEXT_PUBLIC_DELETE_ALL_CHATS_ENABLED && "pb-20"
}`}
>
{!isHistoryEmpty && ( {!isHistoryEmpty && (
<> <>
{Object.entries(groupedChatSesssions) {Object.entries(groupedChatSesssions)
@@ -479,17 +472,6 @@ export function PagesTab({
</p> </p>
)} )}
</div> </div>
{showDeleteAllModal && NEXT_PUBLIC_DELETE_ALL_CHATS_ENABLED && (
<div className="absolute w-full border-t border-t-border bg-background-100 bottom-0 left-0 p-4">
<button
className="px-4 w-full py-2 px-4 text-text-600 hover:text-text-800 bg-background-125 border border-border-strong/50 shadow-sm rounded-md transition-colors duration-200 flex items-center justify-center text-sm"
onClick={showDeleteAllModal}
>
<FiTrash2 className="mr-2" size={14} />
Clear All History
</button>
</div>
)}
</div> </div>
); );
} }

View File

@@ -82,9 +82,6 @@ export const NEXT_PUBLIC_FORGOT_PASSWORD_ENABLED =
export const NEXT_PUBLIC_TEST_ENV = export const NEXT_PUBLIC_TEST_ENV =
process.env.NEXT_PUBLIC_TEST_ENV?.toLowerCase() === "true"; process.env.NEXT_PUBLIC_TEST_ENV?.toLowerCase() === "true";
export const NEXT_PUBLIC_DELETE_ALL_CHATS_ENABLED =
process.env.NEXT_PUBLIC_DELETE_ALL_CHATS_ENABLED?.toLowerCase() === "true";
export const NEXT_PUBLIC_ENABLE_CHROME_EXTENSION = export const NEXT_PUBLIC_ENABLE_CHROME_EXTENSION =
process.env.NEXT_PUBLIC_ENABLE_CHROME_EXTENSION?.toLowerCase() === "true"; process.env.NEXT_PUBLIC_ENABLE_CHROME_EXTENSION?.toLowerCase() === "true";