From e9c7a5041c31a6f7b2032f06abe19c52d3d4cd8c Mon Sep 17 00:00:00 2001 From: simosmik Date: Thu, 16 Apr 2026 09:05:56 +0000 Subject: [PATCH] feat: deleting from sidebar will now ask whether to remove all data as well --- server/index.js | 7 ++- server/projects.js | 63 ++++++++++--------- .../sidebar/hooks/useSidebarController.ts | 4 +- .../view/subcomponents/SidebarModals.tsx | 42 ++++++------- src/i18n/locales/de/sidebar.json | 20 +++--- src/i18n/locales/en/sidebar.json | 20 +++--- src/i18n/locales/ja/sidebar.json | 20 +++--- src/i18n/locales/ko/sidebar.json | 20 +++--- src/i18n/locales/ru/sidebar.json | 20 +++--- src/i18n/locales/zh-CN/sidebar.json | 20 +++--- src/utils/api.js | 11 +++- 11 files changed, 135 insertions(+), 112 deletions(-) diff --git a/server/index.js b/server/index.js index eee06d9c..86ded977 100755 --- a/server/index.js +++ b/server/index.js @@ -494,12 +494,15 @@ app.put('/api/sessions/:sessionId/rename', authenticateToken, async (req, res) = } }); -// Delete project endpoint (force=true to delete with sessions) +// Delete project endpoint +// force=true to allow removal even when sessions exist +// deleteData=true to also delete session/memory files on disk (destructive) app.delete('/api/projects/:projectName', authenticateToken, async (req, res) => { try { const { projectName } = req.params; const force = req.query.force === 'true'; - await deleteProject(projectName, force); + const deleteData = req.query.deleteData === 'true'; + await deleteProject(projectName, force, deleteData); res.json({ success: true }); } catch (error) { res.status(500).json({ error: error.message }); diff --git a/server/projects.js b/server/projects.js index c7000890..67184af0 100755 --- a/server/projects.js +++ b/server/projects.js @@ -1163,8 +1163,9 @@ async function isProjectEmpty(projectName) { } } -// Delete a project (force=true to delete even with sessions) -async function deleteProject(projectName, force = false) { +// Remove a project from the UI. +// When deleteData=true, also delete session/memory files on disk (destructive). +async function deleteProject(projectName, force = false, deleteData = false) { const projectDir = path.join(os.homedir(), '.claude', 'projects', projectName); try { @@ -1174,48 +1175,50 @@ async function deleteProject(projectName, force = false) { } const config = await loadProjectConfig(); - let projectPath = config[projectName]?.path || config[projectName]?.originalPath; - // Fallback to extractProjectDirectory if projectPath is not in config - if (!projectPath) { - projectPath = await extractProjectDirectory(projectName); - } + // Destructive path: delete underlying data when explicitly requested + if (deleteData) { + let projectPath = config[projectName]?.path || config[projectName]?.originalPath; + if (!projectPath) { + projectPath = await extractProjectDirectory(projectName); + } - // Remove the project directory (includes all Claude sessions) - await fs.rm(projectDir, { recursive: true, force: true }); + // Remove the Claude project directory (session logs, memory, subagent data) + await fs.rm(projectDir, { recursive: true, force: true }); - // Delete all Codex sessions associated with this project - if (projectPath) { - try { - const codexSessions = await getCodexSessions(projectPath, { limit: 0 }); - for (const session of codexSessions) { - try { - await deleteCodexSession(session.id); - } catch (err) { - console.warn(`Failed to delete Codex session ${session.id}:`, err.message); + // Delete Codex sessions associated with this project + if (projectPath) { + try { + const codexSessions = await getCodexSessions(projectPath, { limit: 0 }); + for (const session of codexSessions) { + try { + await deleteCodexSession(session.id); + } catch (err) { + console.warn(`Failed to delete Codex session ${session.id}:`, err.message); + } } + } catch (err) { + console.warn('Failed to delete Codex sessions:', err.message); } - } catch (err) { - console.warn('Failed to delete Codex sessions:', err.message); - } - // Delete Cursor sessions directory if it exists - try { - const hash = crypto.createHash('md5').update(projectPath).digest('hex'); - const cursorProjectDir = path.join(os.homedir(), '.cursor', 'chats', hash); - await fs.rm(cursorProjectDir, { recursive: true, force: true }); - } catch (err) { - // Cursor dir may not exist, ignore + // Delete Cursor sessions directory if it exists + try { + const hash = crypto.createHash('md5').update(projectPath).digest('hex'); + const cursorProjectDir = path.join(os.homedir(), '.cursor', 'chats', hash); + await fs.rm(cursorProjectDir, { recursive: true, force: true }); + } catch (err) { + // Cursor dir may not exist, ignore + } } } - // Remove from project config + // Always remove from project config delete config[projectName]; await saveProjectConfig(config); return true; } catch (error) { - console.error(`Error deleting project ${projectName}:`, error); + console.error(`Error removing project ${projectName}:`, error); throw error; } } diff --git a/src/components/sidebar/hooks/useSidebarController.ts b/src/components/sidebar/hooks/useSidebarController.ts index 37570a55..b21f13ad 100644 --- a/src/components/sidebar/hooks/useSidebarController.ts +++ b/src/components/sidebar/hooks/useSidebarController.ts @@ -452,7 +452,7 @@ export function useSidebarController({ [getProjectSessions], ); - const confirmDeleteProject = useCallback(async () => { + const confirmDeleteProject = useCallback(async (deleteData = false) => { if (!deleteConfirmation) { return; } @@ -464,7 +464,7 @@ export function useSidebarController({ setDeletingProjects((prev) => new Set([...prev, project.name])); try { - const response = await api.deleteProject(project.name, !isEmpty); + const response = await api.deleteProject(project.name, !isEmpty, deleteData); if (response.ok) { onProjectDelete?.(project.name); diff --git a/src/components/sidebar/view/subcomponents/SidebarModals.tsx b/src/components/sidebar/view/subcomponents/SidebarModals.tsx index 3f6cd4f8..6d6d69d3 100644 --- a/src/components/sidebar/view/subcomponents/SidebarModals.tsx +++ b/src/components/sidebar/view/subcomponents/SidebarModals.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react'; import ReactDOM from 'react-dom'; -import { AlertTriangle, Trash2 } from 'lucide-react'; +import { AlertTriangle, EyeOff, Trash2 } from 'lucide-react'; import type { TFunction } from 'i18next'; import { Button } from '../../../../shared/view/ui'; import Settings from '../../../settings/view/Settings'; @@ -22,7 +22,7 @@ type SidebarModalsProps = { onProjectCreated: () => void; deleteConfirmation: DeleteProjectConfirmation | null; onCancelDeleteProject: () => void; - onConfirmDeleteProject: () => void; + onConfirmDeleteProject: (deleteData?: boolean) => void; sessionDeleteConfirmation: SessionDeleteConfirmation | null; onCancelDeleteSession: () => void; onConfirmDeleteSession: () => void; @@ -104,8 +104,8 @@ export default function SidebarModals({
-
- +
+

@@ -119,32 +119,32 @@ export default function SidebarModals({ ?

{deleteConfirmation.sessionCount > 0 && ( -
-

- {t('deleteConfirmation.sessionCount', { count: deleteConfirmation.sessionCount })} -

-

- {t('deleteConfirmation.allConversationsDeleted')} -

-
+

+ {t('deleteConfirmation.sessionCount', { count: deleteConfirmation.sessionCount })} +

)} -

- {t('deleteConfirmation.cannotUndo')} -

-
- +
diff --git a/src/i18n/locales/de/sidebar.json b/src/i18n/locales/de/sidebar.json index 8b26756c..b2df5190 100644 --- a/src/i18n/locales/de/sidebar.json +++ b/src/i18n/locales/de/sidebar.json @@ -2,7 +2,7 @@ "projects": { "title": "Projekte", "newProject": "Neues Projekt", - "deleteProject": "Projekt löschen", + "deleteProject": "Projekt entfernen", "renameProject": "Projekt umbenennen", "noProjects": "Keine Projekte gefunden", "loadingProjects": "Projekte werden geladen...", @@ -40,7 +40,7 @@ "createProject": "Neues Projekt erstellen", "refresh": "Projekte und Sitzungen aktualisieren (Strg+R)", "renameProject": "Projekt umbenennen (F2)", - "deleteProject": "Leeres Projekt löschen (Entf)", + "deleteProject": "Projekt aus Seitenleiste entfernen (Entf)", "addToFavorites": "Zu Favoriten hinzufügen", "removeFromFavorites": "Aus Favoriten entfernen", "editSessionName": "Sitzungsname manuell bearbeiten", @@ -95,14 +95,14 @@ "deleteSuccess": "Erfolgreich gelöscht", "errorOccurred": "Ein Fehler ist aufgetreten", "deleteSessionConfirm": "Möchtest du diese Sitzung wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.", - "deleteProjectConfirm": "Möchtest du dieses leere Projekt wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.", + "deleteProjectConfirm": "Projekt aus der Seitenleiste entfernen? Deine Projektdateien, Erinnerungen und Sitzungsdaten werden nicht gelöscht.", "enterProjectPath": "Bitte gib einen Projektpfad ein", "deleteSessionFailed": "Sitzung konnte nicht gelöscht werden. Bitte erneut versuchen.", "deleteSessionError": "Fehler beim Löschen der Sitzung. Bitte erneut versuchen.", "renameSessionFailed": "Sitzung konnte nicht umbenannt werden. Bitte erneut versuchen.", "renameSessionError": "Fehler beim Umbenennen der Sitzung. Bitte erneut versuchen.", - "deleteProjectFailed": "Projekt konnte nicht gelöscht werden. Bitte erneut versuchen.", - "deleteProjectError": "Fehler beim Löschen des Projekts. Bitte erneut versuchen.", + "deleteProjectFailed": "Projekt konnte nicht entfernt werden. Bitte erneut versuchen.", + "deleteProjectError": "Fehler beim Entfernen des Projekts. Bitte erneut versuchen.", "createProjectFailed": "Projekt konnte nicht erstellt werden. Bitte erneut versuchen.", "createProjectError": "Fehler beim Erstellen des Projekts. Bitte erneut versuchen." }, @@ -122,12 +122,14 @@ "projectsScanned_other": "{{count}} Projekte durchsucht" }, "deleteConfirmation": { - "deleteProject": "Projekt löschen", + "deleteProject": "Projekt entfernen", "deleteSession": "Sitzung löschen", - "confirmDelete": "Möchtest du wirklich löschen", + "confirmDelete": "Was möchtest du mit", "sessionCount_one": "Dieses Projekt enthält {{count}} Unterhaltung.", "sessionCount_other": "Dieses Projekt enthält {{count}} Unterhaltungen.", - "allConversationsDeleted": "Alle Unterhaltungen werden dauerhaft gelöscht.", - "cannotUndo": "Diese Aktion kann nicht rückgängig gemacht werden." + "removeFromSidebar": "Nur aus der Seitenleiste entfernen", + "deleteAllData": "Alle Daten dauerhaft löschen", + "allConversationsDeleted": "Das Projekt wird aus der Seitenleiste entfernt. Deine Dateien, Erinnerungen und Sitzungsdaten bleiben erhalten.", + "cannotUndo": "Du kannst das Projekt später erneut hinzufügen." } } diff --git a/src/i18n/locales/en/sidebar.json b/src/i18n/locales/en/sidebar.json index eab0a3f3..7b3452cb 100644 --- a/src/i18n/locales/en/sidebar.json +++ b/src/i18n/locales/en/sidebar.json @@ -2,7 +2,7 @@ "projects": { "title": "Projects", "newProject": "New Project", - "deleteProject": "Delete Project", + "deleteProject": "Remove Project", "renameProject": "Rename Project", "noProjects": "No projects found", "loadingProjects": "Loading projects...", @@ -40,7 +40,7 @@ "createProject": "Create new project", "refresh": "Refresh projects and sessions (Ctrl+R)", "renameProject": "Rename project (F2)", - "deleteProject": "Delete empty project (Delete)", + "deleteProject": "Remove project from sidebar (Delete)", "addToFavorites": "Add to favorites", "removeFromFavorites": "Remove from favorites", "editSessionName": "Manually edit session name", @@ -95,14 +95,14 @@ "deleteSuccess": "Deleted successfully", "errorOccurred": "An error occurred", "deleteSessionConfirm": "Are you sure you want to delete this session? This action cannot be undone.", - "deleteProjectConfirm": "Are you sure you want to delete this empty project? This action cannot be undone.", + "deleteProjectConfirm": "Remove this project from the sidebar? Your project files, memories, and session data will not be deleted.", "enterProjectPath": "Please enter a project path", "deleteSessionFailed": "Failed to delete session. Please try again.", "deleteSessionError": "Error deleting session. Please try again.", "renameSessionFailed": "Failed to rename session. Please try again.", "renameSessionError": "Error renaming session. Please try again.", - "deleteProjectFailed": "Failed to delete project. Please try again.", - "deleteProjectError": "Error deleting project. Please try again.", + "deleteProjectFailed": "Failed to remove project. Please try again.", + "deleteProjectError": "Error removing project. Please try again.", "createProjectFailed": "Failed to create project. Please try again.", "createProjectError": "Error creating project. Please try again." }, @@ -122,12 +122,14 @@ "projectsScanned_other": "{{count}} projects scanned" }, "deleteConfirmation": { - "deleteProject": "Delete Project", + "deleteProject": "Remove Project", "deleteSession": "Delete Session", - "confirmDelete": "Are you sure you want to delete", + "confirmDelete": "What would you like to do with", "sessionCount_one": "This project contains {{count}} conversation.", "sessionCount_other": "This project contains {{count}} conversations.", - "allConversationsDeleted": "All conversations will be permanently deleted.", - "cannotUndo": "This action cannot be undone." + "removeFromSidebar": "Remove from sidebar only", + "deleteAllData": "Delete all data permanently", + "allConversationsDeleted": "The project will be removed from the sidebar. Your files, memories, and session data will be preserved.", + "cannotUndo": "You can re-add the project later." } } diff --git a/src/i18n/locales/ja/sidebar.json b/src/i18n/locales/ja/sidebar.json index 4590c752..33c17399 100644 --- a/src/i18n/locales/ja/sidebar.json +++ b/src/i18n/locales/ja/sidebar.json @@ -2,7 +2,7 @@ "projects": { "title": "プロジェクト", "newProject": "新規プロジェクト", - "deleteProject": "プロジェクトを削除", + "deleteProject": "プロジェクトを除去", "renameProject": "プロジェクト名を変更", "noProjects": "プロジェクトが見つかりません", "loadingProjects": "プロジェクトを読み込んでいます...", @@ -40,7 +40,7 @@ "createProject": "新しいプロジェクトを作成", "refresh": "プロジェクトとセッションを更新 (Ctrl+R)", "renameProject": "プロジェクト名を変更 (F2)", - "deleteProject": "空のプロジェクトを削除 (Delete)", + "deleteProject": "サイドバーからプロジェクトを除去 (Delete)", "addToFavorites": "お気に入りに追加", "removeFromFavorites": "お気に入りから削除", "editSessionName": "セッション名を手動で編集", @@ -94,14 +94,14 @@ "deleteSuccess": "削除しました", "errorOccurred": "エラーが発生しました", "deleteSessionConfirm": "このセッションを削除してもよろしいですか?この操作は取り消せません。", - "deleteProjectConfirm": "この空のプロジェクトを削除してもよろしいですか?この操作は取り消せません。", + "deleteProjectConfirm": "サイドバーからこのプロジェクトを除去しますか?プロジェクトファイル、メモリ、セッションデータは削除されません。", "enterProjectPath": "プロジェクトのパスを入力してください", "deleteSessionFailed": "セッションの削除に失敗しました。もう一度お試しください。", "deleteSessionError": "セッションの削除でエラーが発生しました。もう一度お試しください。", "renameSessionFailed": "セッション名の変更に失敗しました。もう一度お試しください。", "renameSessionError": "セッション名の変更でエラーが発生しました。もう一度お試しください。", - "deleteProjectFailed": "プロジェクトの削除に失敗しました。もう一度お試しください。", - "deleteProjectError": "プロジェクトの削除でエラーが発生しました。もう一度お試しください。", + "deleteProjectFailed": "プロジェクトの除去に失敗しました。もう一度お試しください。", + "deleteProjectError": "プロジェクトの除去でエラーが発生しました。もう一度お試しください。", "createProjectFailed": "プロジェクトの作成に失敗しました。もう一度お試しください。", "createProjectError": "プロジェクトの作成でエラーが発生しました。もう一度お試しください。" }, @@ -109,11 +109,13 @@ "updateAvailable": "アップデートあり" }, "deleteConfirmation": { - "deleteProject": "プロジェクトを削除", + "deleteProject": "プロジェクトを除去", "deleteSession": "セッションを削除", - "confirmDelete": "本当に削除しますか?", + "confirmDelete": "このプロジェクトをどうしますか:", "sessionCount": "このプロジェクトには{{count}}件の会話があります。", - "allConversationsDeleted": "すべての会話が完全に削除されます。", - "cannotUndo": "この操作は取り消せません。" + "removeFromSidebar": "サイドバーからのみ除去", + "deleteAllData": "すべてのデータを完全に削除", + "allConversationsDeleted": "プロジェクトはサイドバーから除去されます。ファイル、メモリ、セッションデータは保持されます。", + "cannotUndo": "後からプロジェクトを再追加できます。" } } diff --git a/src/i18n/locales/ko/sidebar.json b/src/i18n/locales/ko/sidebar.json index cda7eab2..d7fcafaa 100644 --- a/src/i18n/locales/ko/sidebar.json +++ b/src/i18n/locales/ko/sidebar.json @@ -2,7 +2,7 @@ "projects": { "title": "프로젝트", "newProject": "새 프로젝트", - "deleteProject": "프로젝트 삭제", + "deleteProject": "프로젝트 제거", "renameProject": "프로젝트 이름 변경", "noProjects": "프로젝트가 없습니다", "loadingProjects": "프로젝트 로딩 중...", @@ -40,7 +40,7 @@ "createProject": "새 프로젝트 생성", "refresh": "프로젝트 및 세션 새로고침 (Ctrl+R)", "renameProject": "프로젝트 이름 변경 (F2)", - "deleteProject": "빈 프로젝트 삭제 (Delete)", + "deleteProject": "사이드바에서 프로젝트 제거 (Delete)", "addToFavorites": "즐겨찾기에 추가", "removeFromFavorites": "즐겨찾기에서 제거", "editSessionName": "세션 이름 직접 편집", @@ -94,14 +94,14 @@ "deleteSuccess": "삭제되었습니다", "errorOccurred": "오류가 발생했습니다", "deleteSessionConfirm": "이 세션을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.", - "deleteProjectConfirm": "이 빈 프로젝트를 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.", + "deleteProjectConfirm": "사이드바에서 이 프로젝트를 제거하시겠습니까? 프로젝트 파일, 메모리 및 세션 데이터는 삭제되지 않습니다.", "enterProjectPath": "프로젝트 경로를 입력해주세요", "deleteSessionFailed": "세션 삭제 실패. 다시 시도해주세요.", "deleteSessionError": "세션 삭제 오류. 다시 시도해주세요.", "renameSessionFailed": "세션 이름 변경 실패. 다시 시도해주세요.", "renameSessionError": "세션 이름 변경 오류. 다시 시도해주세요.", - "deleteProjectFailed": "프로젝트 삭제 실패. 다시 시도해주세요.", - "deleteProjectError": "프로젝트 삭제 오류. 다시 시도해주세요.", + "deleteProjectFailed": "프로젝트 제거 실패. 다시 시도해주세요.", + "deleteProjectError": "프로젝트 제거 오류. 다시 시도해주세요.", "createProjectFailed": "프로젝트 생성 실패. 다시 시도해주세요.", "createProjectError": "프로젝트 생성 오류. 다시 시도해주세요." }, @@ -109,12 +109,14 @@ "updateAvailable": "업데이트 가능" }, "deleteConfirmation": { - "deleteProject": "프로젝트 삭제", + "deleteProject": "프로젝트 제거", "deleteSession": "세션 삭제", - "confirmDelete": "정말 삭제하시겠습니까", + "confirmDelete": "이 프로젝트를 어떻게 하시겠습니까:", "sessionCount_one": "이 프로젝트에는 {{count}}개의 대화가 있습니다.", "sessionCount_other": "이 프로젝트에는 {{count}}개의 대화가 있습니다.", - "allConversationsDeleted": "모든 대화가 영구적으로 삭제됩니다.", - "cannotUndo": "이 작업은 취소할 수 없습니다." + "removeFromSidebar": "사이드바에서만 제거", + "deleteAllData": "모든 데이터 영구 삭제", + "allConversationsDeleted": "프로젝트가 사이드바에서 제거됩니다. 파일, 메모리 및 세션 데이터는 보존됩니다.", + "cannotUndo": "나중에 프로젝트를 다시 추가할 수 있습니다." } } \ No newline at end of file diff --git a/src/i18n/locales/ru/sidebar.json b/src/i18n/locales/ru/sidebar.json index 71250d2f..9af33d54 100644 --- a/src/i18n/locales/ru/sidebar.json +++ b/src/i18n/locales/ru/sidebar.json @@ -2,7 +2,7 @@ "projects": { "title": "Проекты", "newProject": "Новый проект", - "deleteProject": "Удалить проект", + "deleteProject": "Убрать проект", "renameProject": "Переименовать проект", "noProjects": "Проекты не найдены", "loadingProjects": "Загрузка проектов...", @@ -40,7 +40,7 @@ "createProject": "Создать новый проект", "refresh": "Обновить проекты и сеансы (Ctrl+R)", "renameProject": "Переименовать проект (F2)", - "deleteProject": "Удалить пустой проект (Delete)", + "deleteProject": "Убрать проект из боковой панели (Delete)", "addToFavorites": "Добавить в избранное", "removeFromFavorites": "Удалить из избранного", "editSessionName": "Вручную редактировать имя сеанса", @@ -95,14 +95,14 @@ "deleteSuccess": "Успешно удалено", "errorOccurred": "Произошла ошибка", "deleteSessionConfirm": "Вы уверены, что хотите удалить этот сеанс? Это действие нельзя отменить.", - "deleteProjectConfirm": "Вы уверены, что хотите удалить этот пустой проект? Это действие нельзя отменить.", + "deleteProjectConfirm": "Убрать этот проект из боковой панели? Файлы проекта, воспоминания и данные сеансов не будут удалены.", "enterProjectPath": "Пожалуйста, введите путь к проекту", "deleteSessionFailed": "Не удалось удалить сеанс. Попробуйте снова.", "deleteSessionError": "Ошибка при удалении сеанса. Попробуйте снова.", "renameSessionFailed": "Не удалось переименовать сеанс. Попробуйте снова.", "renameSessionError": "Ошибка при переименовании сеанса. Попробуйте снова.", - "deleteProjectFailed": "Не удалось удалить проект. Попробуйте снова.", - "deleteProjectError": "Ошибка при удалении проекта. Попробуйте снова.", + "deleteProjectFailed": "Не удалось убрать проект. Попробуйте снова.", + "deleteProjectError": "Ошибка при удалении проекта из списка. Попробуйте снова.", "createProjectFailed": "Не удалось создать проект. Попробуйте снова.", "createProjectError": "Ошибка при создании проекта. Попробуйте снова." }, @@ -126,14 +126,16 @@ "projectsScanned_other": "{{count}} проектов просканировано" }, "deleteConfirmation": { - "deleteProject": "Удалить проект", + "deleteProject": "Убрать проект", "deleteSession": "Удалить сеанс", - "confirmDelete": "Вы уверены, что хотите удалить", + "confirmDelete": "Что вы хотите сделать с", "sessionCount_one": "Этот проект содержит {{count}} разговор.", "sessionCount_few": "Этот проект содержит {{count}} разговора.", "sessionCount_many": "Этот проект содержит {{count}} разговоров.", "sessionCount_other": "Этот проект содержит {{count}} разговоров.", - "allConversationsDeleted": "Все разговоры будут удалены навсегда.", - "cannotUndo": "Это действие нельзя отменить." + "removeFromSidebar": "Убрать только из боковой панели", + "deleteAllData": "Удалить все данные навсегда", + "allConversationsDeleted": "Проект будет убран из боковой панели. Ваши файлы, воспоминания и данные сеансов сохранятся.", + "cannotUndo": "Вы сможете добавить проект позже." } } diff --git a/src/i18n/locales/zh-CN/sidebar.json b/src/i18n/locales/zh-CN/sidebar.json index 3a28778c..85053d92 100644 --- a/src/i18n/locales/zh-CN/sidebar.json +++ b/src/i18n/locales/zh-CN/sidebar.json @@ -2,7 +2,7 @@ "projects": { "title": "项目", "newProject": "新建项目", - "deleteProject": "删除项目", + "deleteProject": "移除项目", "renameProject": "重命名项目", "noProjects": "未找到项目", "loadingProjects": "加载项目中...", @@ -40,7 +40,7 @@ "createProject": "创建新项目", "refresh": "刷新项目和会话 (Ctrl+R)", "renameProject": "重命名项目 (F2)", - "deleteProject": "删除空项目 (Delete)", + "deleteProject": "从侧边栏移除项目 (Delete)", "addToFavorites": "添加到收藏", "removeFromFavorites": "从收藏移除", "editSessionName": "手动编辑会话名称", @@ -95,14 +95,14 @@ "deleteSuccess": "删除成功", "errorOccurred": "发生错误", "deleteSessionConfirm": "确定要删除此会话吗?此操作无法撤销。", - "deleteProjectConfirm": "确定要删除此空项目吗?此操作无法撤销。", + "deleteProjectConfirm": "从侧边栏移除此项目?您的项目文件、记忆和会话数据不会被删除。", "enterProjectPath": "请输入项目路径", "deleteSessionFailed": "删除会话失败,请重试。", "deleteSessionError": "删除会话时出错,请重试。", "renameSessionFailed": "重命名会话失败,请重试。", "renameSessionError": "重命名会话时出错,请重试。", - "deleteProjectFailed": "删除项目失败,请重试。", - "deleteProjectError": "删除项目时出错,请重试。", + "deleteProjectFailed": "移除项目失败,请重试。", + "deleteProjectError": "移除项目时出错,请重试。", "createProjectFailed": "创建项目失败,请重试。", "createProjectError": "创建项目时出错,请重试。" }, @@ -122,12 +122,14 @@ "projectsScanned_other": "{{count}} 个项目已扫描" }, "deleteConfirmation": { - "deleteProject": "删除项目", + "deleteProject": "移除项目", "deleteSession": "删除会话", - "confirmDelete": "您确定要删除", + "confirmDelete": "您想如何处理", "sessionCount_one": "此项目包含 {{count}} 个对话。", "sessionCount_other": "此项目包含 {{count}} 个对话。", - "allConversationsDeleted": "所有对话将被永久删除。", - "cannotUndo": "此操作无法撤销。" + "removeFromSidebar": "仅从侧边栏移除", + "deleteAllData": "永久删除所有数据", + "allConversationsDeleted": "项目将从侧边栏中移除。您的文件、记忆和会话数据将会保留。", + "cannotUndo": "您可以稍后重新添加此项目。" } } diff --git a/src/utils/api.js b/src/utils/api.js index 438cab82..9132c16f 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -89,10 +89,15 @@ export const api = { authenticatedFetch(`/api/gemini/sessions/${sessionId}`, { method: 'DELETE', }), - deleteProject: (projectName, force = false) => - authenticatedFetch(`/api/projects/${projectName}${force ? '?force=true' : ''}`, { + deleteProject: (projectName, force = false, deleteData = false) => { + const params = new URLSearchParams(); + if (force) params.set('force', 'true'); + if (deleteData) params.set('deleteData', 'true'); + const qs = params.toString(); + return authenticatedFetch(`/api/projects/${projectName}${qs ? `?${qs}` : ''}`, { method: 'DELETE', - }), + }); + }, searchConversationsUrl: (query, limit = 50) => { const token = localStorage.getItem('auth-token'); const params = new URLSearchParams({ q: query, limit: String(limit) });