diff --git a/locales/de.json b/locales/de.json index cd1776ca..c8f73969 100644 --- a/locales/de.json +++ b/locales/de.json @@ -731,6 +731,12 @@ "countMessage": "Modelle werden dauerhaft gelöscht.", "action": "Alle löschen" }, + "checkUpdates": { + "title": "Alle {typePlural} auf Updates prüfen?", + "message": "Damit werden alle {typePlural} in deiner Bibliothek auf Updates geprüft. Bei großen Sammlungen kann das etwas länger dauern.", + "tip": "Du möchtest in Etappen prüfen? Wechsle in den Sammelmodus, wähle die benötigten Modelle aus und nutze anschließend \"Auswahl auf Updates prüfen\".", + "action": "Alles prüfen" + }, "bulkAddTags": { "title": "Tags zu mehreren Modellen hinzufügen", "description": "Tags hinzufügen zu", diff --git a/locales/en.json b/locales/en.json index 6a935263..cbf25fa8 100644 --- a/locales/en.json +++ b/locales/en.json @@ -730,6 +730,12 @@ "countMessage": "models will be permanently deleted.", "action": "Delete All" }, + "checkUpdates": { + "title": "Check updates for all {typePlural}?", + "message": "This checks every {typePlural} in your library for updates. Large collections may take a little longer.", + "tip": "To work in smaller batches, switch to bulk mode, choose the ones you need, then use \"Check Updates for Selected\".", + "action": "Check All" + }, "bulkAddTags": { "title": "Add Tags to Multiple Models", "description": "Add tags to", diff --git a/locales/es.json b/locales/es.json index 5033beaa..bae80faf 100644 --- a/locales/es.json +++ b/locales/es.json @@ -730,6 +730,12 @@ "countMessage": "modelos serán eliminados permanentemente.", "action": "Eliminar todo" }, + "checkUpdates": { + "title": "¿Comprobar actualizaciones para todos los {typePlural}?", + "message": "Esto comprobará las actualizaciones de todos los {typePlural} de tu biblioteca. En colecciones grandes puede tardar un poco más.", + "tip": "¿Quieres hacerlo por partes? Activa el modo por lotes, selecciona los modelos que necesites y usa \"Comprobar actualizaciones para la selección\".", + "action": "Comprobar todo" + }, "bulkAddTags": { "title": "Añadir etiquetas a múltiples modelos", "description": "Añadir etiquetas a", diff --git a/locales/fr.json b/locales/fr.json index 0ccecae7..9dcbf85b 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -730,6 +730,12 @@ "countMessage": "modèles seront définitivement supprimés.", "action": "Tout supprimer" }, + "checkUpdates": { + "title": "Vérifier les mises à jour pour tous les {typePlural} ?", + "message": "Cette action vérifie les mises à jour pour tous les {typePlural} de votre bibliothèque. Les grandes collections peuvent prendre un peu plus de temps.", + "tip": "Besoin de procéder par étapes ? Passez en mode lot, sélectionnez les modèles souhaités puis utilisez \"Vérifier les mises à jour pour la sélection\".", + "action": "Tout vérifier" + }, "bulkAddTags": { "title": "Ajouter des tags à plusieurs modèles", "description": "Ajouter des tags à", diff --git a/locales/he.json b/locales/he.json index 7303bf54..86e99897 100644 --- a/locales/he.json +++ b/locales/he.json @@ -730,6 +730,12 @@ "countMessage": "מודלים יימחקו לצמיתות.", "action": "מחק הכל" }, + "checkUpdates": { + "title": "לבדוק עדכונים לכל ה-{typePlural}?", + "message": "הפעולה תבדוק עדכונים עבור כל ה-{typePlural} בספרייה שלך. באוספים גדולים זה עלול לקחת מעט יותר זמן.", + "tip": "רוצים לחלק למנות קטנות? עברו למצב קבוצתי, בחרו את המודלים הדרושים ואז השתמשו ב\"בדוק עדכונים לנבחרים\".", + "action": "בדוק הכל" + }, "bulkAddTags": { "title": "הוסף תגיות למספר מודלים", "description": "הוסף תגיות ל-", diff --git a/locales/ja.json b/locales/ja.json index 351b2995..d561df97 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -730,6 +730,12 @@ "countMessage": "モデルが完全に削除されます。", "action": "すべて削除" }, + "checkUpdates": { + "title": "すべての{type}の更新を確認しますか?", + "message": "ライブラリ内のすべての{type}で更新を確認します。コレクションが大きい場合は時間がかかることがあります。", + "tip": "少しずつ確認したい場合はバルクモードに切り替え、必要なモデルを選んで「選択項目の更新を確認」を使ってください。", + "action": "すべて確認" + }, "bulkAddTags": { "title": "複数モデルにタグを追加", "description": "タグを追加するモデル:", diff --git a/locales/ko.json b/locales/ko.json index 2b200a49..ab504050 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -730,6 +730,12 @@ "countMessage": "개의 모델이 영구적으로 삭제됩니다.", "action": "모두 삭제" }, + "checkUpdates": { + "title": "{type} 전체 업데이트를 확인할까요?", + "message": "라이브러리에 있는 모든 {type}의 업데이트를 확인합니다. 컬렉션이 클수록 시간이 조금 더 걸릴 수 있습니다.", + "tip": "나눠서 진행하고 싶다면 벌크 모드로 전환해 필요한 모델만 선택한 뒤 \"선택 항목 업데이트 확인\"을 사용하세요.", + "action": "전체 확인" + }, "bulkAddTags": { "title": "여러 모델에 태그 추가", "description": "다음에 태그를 추가합니다:", diff --git a/locales/ru.json b/locales/ru.json index 973b9c9c..0f5015d2 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -730,6 +730,12 @@ "countMessage": "моделей будут удалены навсегда.", "action": "Удалить все" }, + "checkUpdates": { + "title": "Проверить обновления для всех {typePlural}?", + "message": "Будут проверены обновления для всех {typePlural} в вашей библиотеке. Для больших коллекций это может занять немного больше времени.", + "tip": "Хотите проверять по частям? Переключитесь в массовый режим, выберите нужные модели и используйте \"Проверить обновления для выбранных\".", + "action": "Проверить всё" + }, "bulkAddTags": { "title": "Добавить теги к нескольким моделям", "description": "Добавить теги к", diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 0d715b9a..d40e3459 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -730,6 +730,12 @@ "countMessage": "模型将被永久删除。", "action": "全部删除" }, + "checkUpdates": { + "title": "检查所有 {type} 的更新?", + "message": "这会为库中的每个 {type} 检查更新,大型集合可能需要一些时间。", + "tip": "想分批进行?切换到批量模式,选中需要的模型,然后使用“检查所选更新”。", + "action": "检查全部" + }, "bulkAddTags": { "title": "批量添加标签", "description": "为多个模型添加标签", diff --git a/locales/zh-TW.json b/locales/zh-TW.json index b4c4526f..8111fd91 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -730,6 +730,12 @@ "countMessage": "模型將被永久刪除。", "action": "全部刪除" }, + "checkUpdates": { + "title": "要檢查所有 {type} 的更新嗎?", + "message": "這會為資料庫中的每個 {type} 檢查更新,大型收藏可能會花上一些時間。", + "tip": "想分批處理?切換到批次模式,選擇需要的模型,然後使用「檢查所選更新」。", + "action": "全部檢查" + }, "bulkAddTags": { "title": "新增標籤到多個模型", "description": "新增標籤到", diff --git a/static/js/components/controls/PageControls.js b/static/js/components/controls/PageControls.js index 3ab587ae..56171c60 100644 --- a/static/js/components/controls/PageControls.js +++ b/static/js/components/controls/PageControls.js @@ -235,13 +235,22 @@ export class PageControls { this._updateCheckInProgress = true; setLoadingState(true); + const handleComplete = () => { + this._updateCheckInProgress = false; + setLoadingState(false); + }; + try { - await performModelUpdateCheck(); + await performModelUpdateCheck({ + onComplete: handleComplete, + }); } catch (error) { console.error('Failed to check model updates:', error); } finally { - this._updateCheckInProgress = false; - setLoadingState(false); + if (this._updateCheckInProgress) { + this._updateCheckInProgress = false; + setLoadingState(false); + } dropdownGroup?.classList.remove('active'); } } diff --git a/static/js/managers/ModalManager.js b/static/js/managers/ModalManager.js index cd198000..670feaab 100644 --- a/static/js/managers/ModalManager.js +++ b/static/js/managers/ModalManager.js @@ -195,6 +195,18 @@ export class ModalManager { }); } + // Add checkUpdatesConfirmModal registration + const checkUpdatesConfirmModal = document.getElementById('checkUpdatesConfirmModal'); + if (checkUpdatesConfirmModal) { + this.registerModal('checkUpdatesConfirmModal', { + element: checkUpdatesConfirmModal, + onClose: () => { + this.getModal('checkUpdatesConfirmModal').element.classList.remove('show'); + document.body.classList.remove('modal-open'); + } + }); + } + // Add helpModal registration const helpModal = document.getElementById('helpModal'); if (helpModal) { @@ -339,7 +351,8 @@ export class ModalManager { id === "duplicateDeleteModal" || id === "modelDuplicateDeleteModal" || id === "clearCacheModal" || - id === "bulkDeleteModal" + id === "bulkDeleteModal" || + id === "checkUpdatesConfirmModal" ) { modal.element.classList.add("show"); } else { diff --git a/static/js/utils/updateCheckHelpers.js b/static/js/utils/updateCheckHelpers.js index 408a6fe0..05c1978c 100644 --- a/static/js/utils/updateCheckHelpers.js +++ b/static/js/utils/updateCheckHelpers.js @@ -3,6 +3,10 @@ import { translate } from './i18nHelpers.js'; import { showToast } from './uiHelpers.js'; import { getCompleteApiConfig, getCurrentModelType } from '../api/apiConfig.js'; import { resetAndReload } from '../api/modelApiFactory.js'; +import { getStorageItem, setStorageItem } from './storageHelpers.js'; +import { modalManager } from '../managers/ModalManager.js'; + +const CHECK_UPDATES_CONFIRMATION_KEY = 'ack_check_updates_for_all_models'; /** * Perform a model update check using the shared backend endpoint. @@ -22,6 +26,12 @@ export async function performModelUpdateCheck({ onStart, onComplete } = {}) { return { status: 'unsupported', displayName, records: [], error: null }; } + const proceed = await ensureCheckUpdatesConfirmation(displayName); + if (!proceed) { + onComplete?.({ status: 'cancelled', displayName, records: [], error: null }); + return { status: 'cancelled', displayName, records: [], error: null }; + } + const loadingMessage = translate( 'globalContextMenu.checkModelUpdates.loading', { type: displayName }, @@ -83,3 +93,101 @@ export async function performModelUpdateCheck({ onStart, onComplete } = {}) { return { status, displayName, records, error }; } + +function getTypePlural(displayName) { + if (!displayName) { + return 'models'; + } + + const lower = displayName.toLowerCase(); + if (lower.endsWith('s')) { + return displayName; + } + + return `${displayName}s`; +} + +async function ensureCheckUpdatesConfirmation(displayName) { + const hasConfirmed = getStorageItem(CHECK_UPDATES_CONFIRMATION_KEY, false); + if (hasConfirmed) { + return true; + } + + const modalElement = document.getElementById('checkUpdatesConfirmModal'); + if (!modalElement) { + return true; + } + + const typePlural = getTypePlural(displayName); + + const titleElement = modalElement.querySelector('[data-role="title"]'); + if (titleElement) { + titleElement.textContent = translate( + 'modals.checkUpdates.title', + { type: displayName, typePlural }, + `Check updates for all ${typePlural}?` + ); + } + + const messageElement = modalElement.querySelector('[data-role="message"]'); + if (messageElement) { + messageElement.textContent = translate( + 'modals.checkUpdates.message', + { type: displayName, typePlural }, + `This checks every ${typePlural} in your library for updates. Large collections may take a little longer.` + ); + } + + const tipElement = modalElement.querySelector('[data-role="tip"]'); + if (tipElement) { + tipElement.textContent = translate( + 'modals.checkUpdates.tip', + { type: displayName, typePlural }, + 'To work in smaller batches, switch to bulk mode, pick the ones you need, then use "Check Updates for Selected".' + ); + } + + const confirmButton = modalElement.querySelector('[data-action="confirm-check-updates"]'); + const cancelButton = modalElement.querySelector('[data-action="cancel-check-updates"]'); + + if (!confirmButton || !cancelButton) { + return true; + } + + return new Promise((resolve) => { + let resolved = false; + + const cleanup = () => { + confirmButton.removeEventListener('click', handleConfirm); + cancelButton.removeEventListener('click', handleCancel); + }; + + const finalize = (proceed) => { + if (resolved) { + return; + } + + resolved = true; + cleanup(); + resolve(proceed); + }; + + const handleConfirm = (event) => { + event.preventDefault(); + setStorageItem(CHECK_UPDATES_CONFIRMATION_KEY, true); + finalize(true); + modalManager.closeModal('checkUpdatesConfirmModal'); + }; + + const handleCancel = (event) => { + event.preventDefault(); + finalize(false); + modalManager.closeModal('checkUpdatesConfirmModal'); + }; + + confirmButton.addEventListener('click', handleConfirm); + cancelButton.addEventListener('click', handleCancel); + + modalManager.showModal('checkUpdatesConfirmModal', null, () => finalize(false)); + }); +} diff --git a/templates/components/modals/confirm_modals.html b/templates/components/modals/confirm_modals.html index 0da2ffe9..4636b87b 100644 --- a/templates/components/modals/confirm_modals.html +++ b/templates/components/modals/confirm_modals.html @@ -67,4 +67,17 @@ + + + +