diff --git a/src/interface/web/app/settings/page.tsx b/src/interface/web/app/settings/page.tsx index 9b845987..14929fa0 100644 --- a/src/interface/web/app/settings/page.tsx +++ b/src/interface/web/app/settings/page.tsx @@ -595,48 +595,48 @@ export default function SettingsView() { } }; - const disconnectContent = async (type: string) => { + const disconnectContent = async (source: string) => { try { - const response = await fetch(`/api/content/${type}`, { + const response = await fetch(`/api/content/source/${source}`, { method: "DELETE", headers: { "Content-Type": "application/json", }, }); - if (!response.ok) throw new Error(`Failed to disconnect ${type}`); + if (!response.ok) throw new Error(`Failed to disconnect ${source}`); // Set updated user settings if (userConfig) { let newUserConfig = userConfig; - if (type === "computer") { + if (source === "computer") { newUserConfig.enabled_content_source.computer = false; - } else if (type === "notion") { + } else if (source === "notion") { newUserConfig.enabled_content_source.notion = false; newUserConfig.notion_token = null; setNotionToken(newUserConfig.notion_token); - } else if (type === "github") { + } else if (source === "github") { newUserConfig.enabled_content_source.github = false; } setUserConfig(newUserConfig); } // Notify user about disconnecting content source - if (type === "computer") { + if (source === "computer") { toast({ title: `✅ Deleted Synced Files`, description: "Your synced documents have been deleted.", }); } else { toast({ - title: `✅ Disconnected ${type}`, - description: `Your ${type} integration to Khoj has been disconnected.`, + title: `✅ Disconnected ${source}`, + description: `Your ${source} integration to Khoj has been disconnected.`, }); } } catch (error) { - console.error(`Error disconnecting ${type}:`, error); + console.error(`Error disconnecting ${source}:`, error); toast({ - title: `⚠️ Failed to Disconnect ${type}`, - description: `Failed to disconnect from ${type}. Try again or contact team@khoj.dev`, + title: `⚠️ Failed to Disconnect ${source}`, + description: `Failed to disconnect from ${source}. Try again or contact team@khoj.dev`, }); } }; diff --git a/src/khoj/database/adapters/__init__.py b/src/khoj/database/adapters/__init__.py index ccbbcd99..ae979a8a 100644 --- a/src/khoj/database/adapters/__init__.py +++ b/src/khoj/database/adapters/__init__.py @@ -1549,6 +1549,11 @@ class FileObjectAdapters: async def adelete_file_object_by_name(user: KhojUser, file_name: str): return await FileObject.objects.filter(user=user, file_name=file_name).adelete() + @staticmethod + @arequire_valid_user + async def adelete_file_objects_by_names(user: KhojUser, file_names: List[str]): + return await FileObject.objects.filter(user=user, file_name__in=file_names).adelete() + @staticmethod @arequire_valid_user async def adelete_all_file_objects(user: KhojUser): diff --git a/src/khoj/routers/api_content.py b/src/khoj/routers/api_content.py index d9412629..8762681f 100644 --- a/src/khoj/routers/api_content.py +++ b/src/khoj/routers/api_content.py @@ -420,7 +420,7 @@ async def get_content_source( return await sync_to_async(list)(EntryAdapters.get_all_filenames_by_source(user, content_source)) # type: ignore[call-arg] -@api_content.delete("/{content_source}", status_code=200) +@api_content.delete("/source/{content_source}", status_code=200) @requires(["authenticated"]) async def delete_content_source( request: Request, @@ -434,7 +434,12 @@ async def delete_content_source( raise ValueError(f"Invalid content source: {content_source}") elif content_object != "Computer": await content_object.objects.filter(user=user).adelete() - await sync_to_async(EntryAdapters.delete_all_entries)(user, file_source=content_source) + else: + # Delete file objects from the given source + file_list = await sync_to_async(list)(EntryAdapters.get_all_filenames_by_source(user, content_source)) # type: ignore[call-arg] + await FileObjectAdapters.adelete_file_objects_by_names(user, file_list) + # Delete entries from the given source + await EntryAdapters.adelete_all_entries(user, file_source=content_source) if content_source == DbEntry.EntrySource.NOTION: await NotionConfig.objects.filter(user=user).adelete() @@ -449,7 +454,6 @@ async def delete_content_source( metadata={"content_source": content_source}, ) - enabled_content = await sync_to_async(EntryAdapters.get_unique_file_types)(user) return {"status": "ok"}