fix: add confirmation dialog before deleting extraction history items

Fixes #2975

Add window.confirm() check before deleting individual extraction
history items to prevent accidental data loss. This follows the
same pattern as the existing onClearExtractions function.

Changes:
- Added confirmation dialog in MemorySection.onDeleteExtraction
- Added i18n key 'settings.memoryExtractionDeleteConfirm' to all locales
- Updated useCallback dependency array to include 't'

The confirmation message warns users that the deletion cannot be undone,
providing a safety net against accidental clicks.
This commit is contained in:
xxiaoxiong 2026-05-26 19:33:20 +08:00
parent a4ec7808a6
commit 990261a74d
20 changed files with 21 additions and 1 deletions

View file

@ -1364,6 +1364,7 @@ export function MemorySection({
}, [indexDraft, fireFlash]); }, [indexDraft, fireFlash]);
const onDeleteExtraction = useCallback(async (id: string) => { const onDeleteExtraction = useCallback(async (id: string) => {
if (!window.confirm(t('settings.memoryExtractionDeleteConfirm'))) return;
// Optimistic removal: drop the row immediately so the click feels // Optimistic removal: drop the row immediately so the click feels
// instant. The SSE 'deleted' event will arrive moments later and is // instant. The SSE 'deleted' event will arrive moments later and is
// a no-op against an already-removed id; if the request fails we // a no-op against an already-removed id; if the request fails we
@ -1373,7 +1374,7 @@ export function MemorySection({
if (!ok) { if (!ok) {
void reloadExtractions(); void reloadExtractions();
} }
}, [reloadExtractions]); }, [reloadExtractions, t]);
const onClearExtractions = useCallback(async () => { const onClearExtractions = useCallback(async () => {
if (!window.confirm(t('settings.memoryExtractionsClearConfirm'))) return; if (!window.confirm(t('settings.memoryExtractionsClearConfirm'))) return;

View file

@ -1645,6 +1645,7 @@ export const ar: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'تثبيت', 'settings.libraryInstall': 'تثبيت',

View file

@ -1583,6 +1583,7 @@ export const de: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Installieren', 'settings.libraryInstall': 'Installieren',

View file

@ -2409,6 +2409,7 @@ export const en: Dict = {
'settings.memoryExtractionWritten': 'written', 'settings.memoryExtractionWritten': 'written',
'settings.memoryExtractionDuration': 'in', 'settings.memoryExtractionDuration': 'in',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.memoryExtractionsClearConfirm': 'settings.memoryExtractionsClearConfirm':

View file

@ -1534,6 +1534,7 @@ export const esES: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Instalar', 'settings.libraryInstall': 'Instalar',

View file

@ -1688,6 +1688,7 @@ export const fa: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'نصب', 'settings.libraryInstall': 'نصب',

View file

@ -2307,6 +2307,7 @@ export const fr: Dict = {
'settings.memoryExtractionWritten': 'écrite', 'settings.memoryExtractionWritten': 'écrite',
'settings.memoryExtractionDuration': 'en', 'settings.memoryExtractionDuration': 'en',
'settings.memoryExtractionDelete': 'Supprimer', 'settings.memoryExtractionDelete': 'Supprimer',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Effacer', 'settings.memoryExtractionsClear': 'Effacer',
'settings.memoryExtractionsClearTitle': 'Effacer tout lhistorique dextraction', 'settings.memoryExtractionsClearTitle': 'Effacer tout lhistorique dextraction',
'settings.memoryExtractionsClearConfirm': 'Effacer tout lhistorique des extractions ? Cette action est irréversible.', 'settings.memoryExtractionsClearConfirm': 'Effacer tout lhistorique des extractions ? Cette action est irréversible.',

View file

@ -1655,6 +1655,7 @@ export const hu: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Telepítés', 'settings.libraryInstall': 'Telepítés',

View file

@ -1763,6 +1763,7 @@ export const id: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Instal', 'settings.libraryInstall': 'Instal',

View file

@ -1519,6 +1519,7 @@ export const it: Dict = {
'settings.memoryNoProviderBannerBody': 'Nessuna chiave API trovata per l\'estrattore di memoria. Aggiungi una chiave OpenAI sotto Provider di media, o imposta ANTHROPIC_API_KEY / OPENAI_API_KEY nell\'ambiente, per abilitare l\'estrazione guidata da LLM. L\'estrazione euristica regex è ancora attiva.', 'settings.memoryNoProviderBannerBody': 'Nessuna chiave API trovata per l\'estrattore di memoria. Aggiungi una chiave OpenAI sotto Provider di media, o imposta ANTHROPIC_API_KEY / OPENAI_API_KEY nell\'ambiente, per abilitare l\'estrazione guidata da LLM. L\'estrazione euristica regex è ancora attiva.',
'settings.memoryExtractionProviderOverride': 'impostazioni memoria', 'settings.memoryExtractionProviderOverride': 'impostazioni memoria',
'settings.memoryExtractionDelete': 'Elimina', 'settings.memoryExtractionDelete': 'Elimina',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Cancella', 'settings.memoryExtractionsClear': 'Cancella',
'settings.memoryExtractionsClearTitle': 'Cancella tutta la cronologia di estrazione', 'settings.memoryExtractionsClearTitle': 'Cancella tutta la cronologia di estrazione',
'settings.libraryInstall': 'Installa', 'settings.libraryInstall': 'Installa',

View file

@ -1582,6 +1582,7 @@ export const ja: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'インストール', 'settings.libraryInstall': 'インストール',

View file

@ -1695,6 +1695,7 @@ export const ko: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': '설치', 'settings.libraryInstall': '설치',

View file

@ -1645,6 +1645,7 @@ export const pl: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Zainstaluj', 'settings.libraryInstall': 'Zainstaluj',

View file

@ -1686,6 +1686,7 @@ export const ptBR: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Instalar', 'settings.libraryInstall': 'Instalar',

View file

@ -1686,6 +1686,7 @@ export const ru: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Установить', 'settings.libraryInstall': 'Установить',

View file

@ -1632,6 +1632,7 @@ export const tr: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Yükle', 'settings.libraryInstall': 'Yükle',

View file

@ -1687,6 +1687,7 @@ export const uk: Dict = {
'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.', 'settings.memoryNoProviderBannerBody': 'No API key found for the memory extractor. Add an OpenAI key under Media providers, or set ANTHROPIC_API_KEY / OPENAI_API_KEY in the environment, to enable LLM-driven extraction. Heuristic regex extraction is still active.',
'settings.memoryExtractionProviderOverride': 'memory settings', 'settings.memoryExtractionProviderOverride': 'memory settings',
'settings.memoryExtractionDelete': 'Delete', 'settings.memoryExtractionDelete': 'Delete',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': 'Clear', 'settings.memoryExtractionsClear': 'Clear',
'settings.memoryExtractionsClearTitle': 'Clear all extraction history', 'settings.memoryExtractionsClearTitle': 'Clear all extraction history',
'settings.libraryInstall': 'Встановити', 'settings.libraryInstall': 'Встановити',

View file

@ -2374,6 +2374,7 @@ export const zhCN: Dict = {
'settings.memoryExtractionWritten': '写入', 'settings.memoryExtractionWritten': '写入',
'settings.memoryExtractionDuration': '耗时', 'settings.memoryExtractionDuration': '耗时',
'settings.memoryExtractionDelete': '删除', 'settings.memoryExtractionDelete': '删除',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': '清空', 'settings.memoryExtractionsClear': '清空',
'settings.memoryExtractionsClearTitle': '清空整个抽取历史', 'settings.memoryExtractionsClearTitle': '清空整个抽取历史',
'settings.memoryExtractionsClearConfirm': '确定要清空整个抽取历史吗?此操作无法撤销。', 'settings.memoryExtractionsClearConfirm': '确定要清空整个抽取历史吗?此操作无法撤销。',

View file

@ -1925,6 +1925,7 @@ export const zhTW: Dict = {
'settings.memoryNoProviderBannerBody': '未找到可用的 API keyLLM 抽取已跳過。可以在媒體提供者裡填入 OpenAI key或設定環境變數 ANTHROPIC_API_KEY / OPENAI_API_KEY 來啟用。啟發式抽取仍在執行。', 'settings.memoryNoProviderBannerBody': '未找到可用的 API keyLLM 抽取已跳過。可以在媒體提供者裡填入 OpenAI key或設定環境變數 ANTHROPIC_API_KEY / OPENAI_API_KEY 來啟用。啟發式抽取仍在執行。',
'settings.memoryExtractionProviderOverride': '記憶設定', 'settings.memoryExtractionProviderOverride': '記憶設定',
'settings.memoryExtractionDelete': '刪除', 'settings.memoryExtractionDelete': '刪除',
'settings.memoryExtractionDeleteConfirm': 'Delete this extraction history item? This cannot be undone.',
'settings.memoryExtractionsClear': '清空', 'settings.memoryExtractionsClear': '清空',
'settings.memoryExtractionsClearTitle': '清空整個抽取歷史', 'settings.memoryExtractionsClearTitle': '清空整個抽取歷史',
'settings.libraryInstall': '安裝', 'settings.libraryInstall': '安裝',

View file

@ -627,6 +627,7 @@ export interface Dict {
'settings.memoryExtractionWritten': string; 'settings.memoryExtractionWritten': string;
'settings.memoryExtractionDuration': string; 'settings.memoryExtractionDuration': string;
'settings.memoryExtractionDelete': string; 'settings.memoryExtractionDelete': string;
'settings.memoryExtractionDeleteConfirm': string;
'settings.memoryExtractionsClear': string; 'settings.memoryExtractionsClear': string;
'settings.memoryExtractionsClearTitle': string; 'settings.memoryExtractionsClearTitle': string;
'settings.memoryExtractionsClearConfirm': string; 'settings.memoryExtractionsClearConfirm': string;