feat(recipes): show a summary modal after rematch runs

Replace the post-run toast cascade and the standalone L4 results modal
with a summary modal modeled on the batch download summary: 3-state
header, stat cards (matched / needs review / unresolved / errors),
an L4 review table with per-entry undo, and a copyable report. Wired
into the global, bulk and single-recipe rematch entries; complete
no-op runs keep the lightweight toast. Obsolete results-modal code,
styles and i18n keys are removed.
This commit is contained in:
Will Miao
2026-09-09 10:38:10 +08:00
parent 51cad6f852
commit 4963bf2b2e
23 changed files with 997 additions and 583 deletions
+21 -9
View File
@@ -216,9 +216,6 @@
"label": "Повторное сопоставление рецептов с локальными моделями",
"loading": "Повторное сопоставление рецептов с локальными моделями...",
"success": "Сопоставлено записей: {entries} в рецептах: {recipes}",
"successErrors": "Сопоставлено записей: {entries} в рецептах: {recipes}, ошибок: {failures}",
"allFailed": "Не удалось сопоставить: {failures} из {total} рецептов",
"noMatch": "Не найдено локального сопоставления для {entries} записей в {recipes} рецептах",
"cancelled": "Сопоставление отменено. Обновлено рецептов: {recipes} (записей: {entries})",
"error": "Не удалось выполнить сопоставление рецептов: {message}"
},
@@ -1511,12 +1508,31 @@
"confirmButton": "Сопоставить"
},
"rematchResults": {
"title": "Результаты сопоставления — совпадения по имени файла",
"message": "Эти записи были переподключены по имени файла и могут ссылаться на другую версию модели. Проверьте их и отмените неверные.",
"undo": "Отменить",
"undone": "Отменено",
"undoFailed": "Не удалось отменить сопоставление: {message}"
},
"rematchSummary": {
"title": "[TODO: Translate] Rematch Summary",
"successMessage": "[TODO: Translate] Matched {entries} entries",
"failed": "[TODO: Translate] Rematch failed",
"completedWithWarnings": "[TODO: Translate] Rematch completed — review recommended",
"cancelledNote": "[TODO: Translate] Run cancelled before completion — counts are partial.",
"statMatched": "[TODO: Translate] Matched entries",
"statReview": "[TODO: Translate] Needs review",
"statUnresolved": "[TODO: Translate] Unresolved",
"statErrors": "[TODO: Translate] Errors",
"reviewSection": "[TODO: Translate] Filename matches to review ({count})",
"columnRecipe": "[TODO: Translate] Recipe",
"columnEntry": "[TODO: Translate] Entry",
"columnFile": "[TODO: Translate] Matched file",
"columnUndo": "[TODO: Translate] Undo",
"copyReport": "[TODO: Translate] Copy Report",
"close": "[TODO: Translate] Close",
"scope_global": "[TODO: Translate] All recipes",
"scope_bulk": "[TODO: Translate] Selected recipes",
"scope_single": "[TODO: Translate] Single recipe"
},
"exampleAccess": {
"title": "Локальные примеры изображений",
"message": "Локальные примеры изображений для этой модели не найдены. Варианты просмотра:",
@@ -2239,10 +2255,6 @@
"batchImportBrowseFailed": "Не удалось открыть папку: {message}",
"batchImportDirectorySelected": "Выбрана папка: {path}",
"noRecipesSelected": "Рецепты не выбраны",
"rematchComplete": "Сопоставлено записей: {entries} в рецептах: {recipes}",
"rematchCompleteErrors": "Сопоставлено записей: {entries} в рецептах: {recipes}, ошибок: {failures}",
"rematchAllFailed": "Не удалось сопоставить: {failures} из {total} выбранных рецептов",
"rematchUnmatched": "Не найдено локального сопоставления для {entries} записей в {recipes} рецептах",
"rematchSkipped": "Ни один из {total} выбранных рецептов не требует сопоставления",
"rematchFailed": "Не удалось сопоставить выбранные рецепты: {message}",
"reimporting": "Переимпорт рецепта из источника...",