refactor(ui): group example image download actions into a submenu

Move the 'Download Missing' / 'Re-process All' example image actions
under a single 'Download Example Images' submenu item in the single-model
and bulk context menus, matching the existing send-to-workflow submenu
pattern. Shorten the submenu labels and update all locale translations.
This commit is contained in:
Will Miao
2026-08-03 21:17:42 +08:00
parent dc674098e7
commit 186ef4da78
15 changed files with 105 additions and 66 deletions

View File

@@ -772,8 +772,9 @@
"unfavorite": "Aus Favoriten entfernen", "unfavorite": "Aus Favoriten entfernen",
"deleteAll": "Ausgewählte löschen", "deleteAll": "Ausgewählte löschen",
"downloadMissingLoras": "Fehlende LoRAs herunterladen", "downloadMissingLoras": "Fehlende LoRAs herunterladen",
"downloadMissingExamples": "Fehlende Beispielbilder herunterladen", "downloadExamples": "Beispielbilder herunterladen",
"reprocessExamples": "Beispielbilder erneut verarbeiten", "downloadMissingExamples": "Fehlende herunterladen",
"reprocessExamples": "Alle erneut verarbeiten",
"clear": "Auswahl löschen", "clear": "Auswahl löschen",
"skipMetadataRefreshCount": "Überspringen{count} Modelle", "skipMetadataRefreshCount": "Überspringen{count} Modelle",
"resumeMetadataRefreshCount": "Fortsetzen{count} Modelle", "resumeMetadataRefreshCount": "Fortsetzen{count} Modelle",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "An Workflow senden (Anhängen)", "sendToWorkflowAppend": "An Workflow senden (Anhängen)",
"sendToWorkflowReplace": "An Workflow senden (Ersetzen)", "sendToWorkflowReplace": "An Workflow senden (Ersetzen)",
"openExamples": "Beispiele-Ordner öffnen", "openExamples": "Beispiele-Ordner öffnen",
"downloadExamples": "Fehlende Beispielbilder herunterladen", "downloadExamples": "Beispielbilder herunterladen",
"reprocessExamples": "Beispielbilder erneut verarbeiten", "downloadMissingExamples": "Fehlende herunterladen",
"reprocessExamples": "Alle erneut verarbeiten",
"replacePreview": "Vorschau ersetzen", "replacePreview": "Vorschau ersetzen",
"setContentRating": "Inhaltsbewertung festlegen", "setContentRating": "Inhaltsbewertung festlegen",
"moveToFolder": "In Ordner verschieben", "moveToFolder": "In Ordner verschieben",

View File

@@ -772,8 +772,9 @@
"unfavorite": "Remove from Favorites", "unfavorite": "Remove from Favorites",
"deleteAll": "Delete Selected", "deleteAll": "Delete Selected",
"downloadMissingLoras": "Download Missing LoRAs", "downloadMissingLoras": "Download Missing LoRAs",
"downloadMissingExamples": "Download Missing Example Images", "downloadExamples": "Download Example Images",
"reprocessExamples": "Re-process Example Images", "downloadMissingExamples": "Download Missing",
"reprocessExamples": "Re-process All",
"clear": "Clear Selection", "clear": "Clear Selection",
"skipMetadataRefreshCount": "Skip ({count} models)", "skipMetadataRefreshCount": "Skip ({count} models)",
"resumeMetadataRefreshCount": "Resume ({count} models)", "resumeMetadataRefreshCount": "Resume ({count} models)",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "Send to Workflow (Append)", "sendToWorkflowAppend": "Send to Workflow (Append)",
"sendToWorkflowReplace": "Send to Workflow (Replace)", "sendToWorkflowReplace": "Send to Workflow (Replace)",
"openExamples": "Open Examples Folder", "openExamples": "Open Examples Folder",
"downloadExamples": "Download Missing Example Images", "downloadExamples": "Download Example Images",
"reprocessExamples": "Re-process Example Images", "downloadMissingExamples": "Download Missing",
"reprocessExamples": "Re-process All",
"replacePreview": "Replace Preview", "replacePreview": "Replace Preview",
"setContentRating": "Set Content Rating", "setContentRating": "Set Content Rating",
"moveToFolder": "Move to Folder", "moveToFolder": "Move to Folder",

View File

@@ -772,8 +772,9 @@
"unfavorite": "Quitar de favoritos", "unfavorite": "Quitar de favoritos",
"deleteAll": "Eliminar seleccionados", "deleteAll": "Eliminar seleccionados",
"downloadMissingLoras": "Descargar LoRAs faltantes", "downloadMissingLoras": "Descargar LoRAs faltantes",
"downloadMissingExamples": "Descargar imágenes de ejemplo faltantes", "downloadExamples": "Descargar imágenes de ejemplo",
"reprocessExamples": "Reprocesar imágenes de ejemplo", "downloadMissingExamples": "Descargar faltantes",
"reprocessExamples": "Reprocesar todo",
"clear": "Limpiar selección", "clear": "Limpiar selección",
"skipMetadataRefreshCount": "Omitir{count} modelos", "skipMetadataRefreshCount": "Omitir{count} modelos",
"resumeMetadataRefreshCount": "Reanudar{count} modelos", "resumeMetadataRefreshCount": "Reanudar{count} modelos",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "Enviar al flujo de trabajo (Añadir)", "sendToWorkflowAppend": "Enviar al flujo de trabajo (Añadir)",
"sendToWorkflowReplace": "Enviar al flujo de trabajo (Reemplazar)", "sendToWorkflowReplace": "Enviar al flujo de trabajo (Reemplazar)",
"openExamples": "Abrir carpeta de ejemplos", "openExamples": "Abrir carpeta de ejemplos",
"downloadExamples": "Descargar imágenes de ejemplo faltantes", "downloadExamples": "Descargar imágenes de ejemplo",
"reprocessExamples": "Reprocesar imágenes de ejemplo", "downloadMissingExamples": "Descargar faltantes",
"reprocessExamples": "Reprocesar todo",
"replacePreview": "Reemplazar vista previa", "replacePreview": "Reemplazar vista previa",
"setContentRating": "Establecer clasificación de contenido", "setContentRating": "Establecer clasificación de contenido",
"moveToFolder": "Mover a carpeta", "moveToFolder": "Mover a carpeta",

View File

@@ -772,8 +772,9 @@
"unfavorite": "Retirer des favoris", "unfavorite": "Retirer des favoris",
"deleteAll": "Supprimer la sélection", "deleteAll": "Supprimer la sélection",
"downloadMissingLoras": "Télécharger les LoRAs manquants", "downloadMissingLoras": "Télécharger les LoRAs manquants",
"downloadMissingExamples": "Télécharger les images d'exemple manquantes", "downloadExamples": "Télécharger les images d'exemple",
"reprocessExamples": "Retraiter les images d'exemple", "downloadMissingExamples": "Télécharger les manquantes",
"reprocessExamples": "Tout retraiter",
"clear": "Effacer la sélection", "clear": "Effacer la sélection",
"skipMetadataRefreshCount": "Ignorer{count} modèles", "skipMetadataRefreshCount": "Ignorer{count} modèles",
"resumeMetadataRefreshCount": "Reprendre{count} modèles", "resumeMetadataRefreshCount": "Reprendre{count} modèles",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "Envoyer vers le workflow (Ajouter)", "sendToWorkflowAppend": "Envoyer vers le workflow (Ajouter)",
"sendToWorkflowReplace": "Envoyer vers le workflow (Remplacer)", "sendToWorkflowReplace": "Envoyer vers le workflow (Remplacer)",
"openExamples": "Ouvrir le dossier d'exemples", "openExamples": "Ouvrir le dossier d'exemples",
"downloadExamples": "Télécharger les images d'exemple manquantes", "downloadExamples": "Télécharger les images d'exemple",
"reprocessExamples": "Retraiter les images d'exemple", "downloadMissingExamples": "Télécharger les manquantes",
"reprocessExamples": "Tout retraiter",
"replacePreview": "Remplacer l'aperçu", "replacePreview": "Remplacer l'aperçu",
"setContentRating": "Définir la classification du contenu", "setContentRating": "Définir la classification du contenu",
"moveToFolder": "Déplacer vers un dossier", "moveToFolder": "Déplacer vers un dossier",

View File

@@ -772,8 +772,9 @@
"unfavorite": "הסר ממועדפים", "unfavorite": "הסר ממועדפים",
"deleteAll": "מחק נבחרים", "deleteAll": "מחק נבחרים",
"downloadMissingLoras": "הורדת LoRAs חסרים", "downloadMissingLoras": "הורדת LoRAs חסרים",
"downloadMissingExamples": "הורדת תמונות דוגמה חסרות", "downloadExamples": "הורד תמונות דוגמה",
"reprocessExamples": "עיבוד מחדש של תמונות דוגמה", "downloadMissingExamples": "הורדת חסרים",
"reprocessExamples": "עיבוד מחדש של הכול",
"clear": "נקה בחירה", "clear": "נקה בחירה",
"skipMetadataRefreshCount": "דילוג({count} מודלים)", "skipMetadataRefreshCount": "דילוג({count} מודלים)",
"resumeMetadataRefreshCount": "המשך({count} מודלים)", "resumeMetadataRefreshCount": "המשך({count} מודלים)",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "שלח ל-Workflow (הוסף)", "sendToWorkflowAppend": "שלח ל-Workflow (הוסף)",
"sendToWorkflowReplace": "שלח ל-Workflow (החלף)", "sendToWorkflowReplace": "שלח ל-Workflow (החלף)",
"openExamples": "פתח תיקיית דוגמאות", "openExamples": "פתח תיקיית דוגמאות",
"downloadExamples": "הורדת תמונות דוגמה חסרות", "downloadExamples": "הורד תמונות דוגמה",
"reprocessExamples": "עיבוד מחדש של תמונות דוגמה", "downloadMissingExamples": "הורדת חסרים",
"reprocessExamples": "עיבוד מחדש של הכול",
"replacePreview": "החלף תצוגה מקדימה", "replacePreview": "החלף תצוגה מקדימה",
"setContentRating": "הגדר דירוג תוכן", "setContentRating": "הגדר דירוג תוכן",
"moveToFolder": "העבר לתיקייה", "moveToFolder": "העבר לתיקייה",

View File

@@ -772,8 +772,9 @@
"unfavorite": "お気に入りから削除", "unfavorite": "お気に入りから削除",
"deleteAll": "選択したものを削除", "deleteAll": "選択したものを削除",
"downloadMissingLoras": "不足している LoRA をダウンロード", "downloadMissingLoras": "不足している LoRA をダウンロード",
"downloadMissingExamples": "不足しているサンプル画像をダウンロード", "downloadExamples": "画像をダウンロード",
"reprocessExamples": "サンプル画像を再処理", "downloadMissingExamples": "不足分をダウンロード",
"reprocessExamples": "すべて再処理",
"clear": "選択をクリア", "clear": "選択をクリア",
"skipMetadataRefreshCount": "スキップ({count}モデル)", "skipMetadataRefreshCount": "スキップ({count}モデル)",
"resumeMetadataRefreshCount": "再開({count}モデル)", "resumeMetadataRefreshCount": "再開({count}モデル)",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "ワークフローに送信(追加)", "sendToWorkflowAppend": "ワークフローに送信(追加)",
"sendToWorkflowReplace": "ワークフローに送信(置換)", "sendToWorkflowReplace": "ワークフローに送信(置換)",
"openExamples": "例画像フォルダを開く", "openExamples": "例画像フォルダを開く",
"downloadExamples": "不足しているサンプル画像をダウンロード", "downloadExamples": "画像をダウンロード",
"reprocessExamples": "サンプル画像を再処理", "downloadMissingExamples": "不足分をダウンロード",
"reprocessExamples": "すべて再処理",
"replacePreview": "プレビューを置換", "replacePreview": "プレビューを置換",
"setContentRating": "コンテンツレーティングを設定", "setContentRating": "コンテンツレーティングを設定",
"moveToFolder": "フォルダに移動", "moveToFolder": "フォルダに移動",

View File

@@ -772,8 +772,9 @@
"unfavorite": "즐겨찾기 해제", "unfavorite": "즐겨찾기 해제",
"deleteAll": "선택된 항목 삭제", "deleteAll": "선택된 항목 삭제",
"downloadMissingLoras": "누락된 LoRA 다운로드", "downloadMissingLoras": "누락된 LoRA 다운로드",
"downloadMissingExamples": "누락된 예시 이미지 다운로드", "downloadExamples": "예시 이미지 다운로드",
"reprocessExamples": "예시 이미지 다시 처리", "downloadMissingExamples": "누락된 것만 다운로드",
"reprocessExamples": "모두 다시 처리",
"clear": "선택 지우기", "clear": "선택 지우기",
"skipMetadataRefreshCount": "건너뛰기({count}개 모델)", "skipMetadataRefreshCount": "건너뛰기({count}개 모델)",
"resumeMetadataRefreshCount": "재개({count}개 모델)", "resumeMetadataRefreshCount": "재개({count}개 모델)",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "워크플로로 전송 (추가)", "sendToWorkflowAppend": "워크플로로 전송 (추가)",
"sendToWorkflowReplace": "워크플로로 전송 (교체)", "sendToWorkflowReplace": "워크플로로 전송 (교체)",
"openExamples": "예시 폴더 열기", "openExamples": "예시 폴더 열기",
"downloadExamples": "누락된 예시 이미지 다운로드", "downloadExamples": "예시 이미지 다운로드",
"reprocessExamples": "예시 이미지 다시 처리", "downloadMissingExamples": "누락된 것만 다운로드",
"reprocessExamples": "모두 다시 처리",
"replacePreview": "미리보기 교체", "replacePreview": "미리보기 교체",
"setContentRating": "콘텐츠 등급 설정", "setContentRating": "콘텐츠 등급 설정",
"moveToFolder": "폴더로 이동", "moveToFolder": "폴더로 이동",

View File

@@ -772,8 +772,9 @@
"unfavorite": "Удалить из избранного", "unfavorite": "Удалить из избранного",
"deleteAll": "Удалить выбранные", "deleteAll": "Удалить выбранные",
"downloadMissingLoras": "Скачать отсутствующие LoRAs", "downloadMissingLoras": "Скачать отсутствующие LoRAs",
"downloadMissingExamples": "Загрузить недостающие примеры изображений", "downloadExamples": "Загрузить примеры изображений",
"reprocessExamples": "Повторно обработать примеры изображений", "downloadMissingExamples": "Скачать недостающие",
"reprocessExamples": "Обработать всё заново",
"clear": "Очистить выбор", "clear": "Очистить выбор",
"skipMetadataRefreshCount": "Пропустить({count} моделей)", "skipMetadataRefreshCount": "Пропустить({count} моделей)",
"resumeMetadataRefreshCount": "Возобновить({count} моделей)", "resumeMetadataRefreshCount": "Возобновить({count} моделей)",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "Отправить в Workflow (Добавить)", "sendToWorkflowAppend": "Отправить в Workflow (Добавить)",
"sendToWorkflowReplace": "Отправить в Workflow (Заменить)", "sendToWorkflowReplace": "Отправить в Workflow (Заменить)",
"openExamples": "Открыть папку примеров", "openExamples": "Открыть папку примеров",
"downloadExamples": "Загрузить недостающие примеры изображений", "downloadExamples": "Загрузить примеры изображений",
"reprocessExamples": "Повторно обработать примеры изображений", "downloadMissingExamples": "Скачать недостающие",
"reprocessExamples": "Обработать всё заново",
"replacePreview": "Заменить превью", "replacePreview": "Заменить превью",
"setContentRating": "Установить рейтинг контента", "setContentRating": "Установить рейтинг контента",
"moveToFolder": "Переместить в папку", "moveToFolder": "Переместить в папку",

View File

@@ -772,8 +772,9 @@
"unfavorite": "取消收藏", "unfavorite": "取消收藏",
"deleteAll": "删除已选", "deleteAll": "删除已选",
"downloadMissingLoras": "下载缺失的 LoRAs", "downloadMissingLoras": "下载缺失的 LoRAs",
"downloadMissingExamples": "下载缺失的示例图片", "downloadExamples": "下载示例图片",
"reprocessExamples": "重新处理示例图片", "downloadMissingExamples": "下载缺失的",
"reprocessExamples": "重新处理全部",
"clear": "清除选择", "clear": "清除选择",
"skipMetadataRefreshCount": "跳过({count} 个模型)", "skipMetadataRefreshCount": "跳过({count} 个模型)",
"resumeMetadataRefreshCount": "恢复({count} 个模型)", "resumeMetadataRefreshCount": "恢复({count} 个模型)",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "发送到工作流(追加)", "sendToWorkflowAppend": "发送到工作流(追加)",
"sendToWorkflowReplace": "发送到工作流(替换)", "sendToWorkflowReplace": "发送到工作流(替换)",
"openExamples": "打开示例文件夹", "openExamples": "打开示例文件夹",
"downloadExamples": "下载缺失的示例图片", "downloadExamples": "下载示例图片",
"reprocessExamples": "重新处理示例图片", "downloadMissingExamples": "下载缺失的",
"reprocessExamples": "重新处理全部",
"replacePreview": "替换预览", "replacePreview": "替换预览",
"setContentRating": "设置内容评级", "setContentRating": "设置内容评级",
"moveToFolder": "移动到文件夹", "moveToFolder": "移动到文件夹",

View File

@@ -772,8 +772,9 @@
"unfavorite": "取消收藏", "unfavorite": "取消收藏",
"deleteAll": "刪除所選", "deleteAll": "刪除所選",
"downloadMissingLoras": "下載缺失的 LoRAs", "downloadMissingLoras": "下載缺失的 LoRAs",
"downloadMissingExamples": "下載缺少的範例圖片", "downloadExamples": "下載範例圖片",
"reprocessExamples": "重新處理範例圖片", "downloadMissingExamples": "下載缺少的",
"reprocessExamples": "重新處理全部",
"clear": "清除選取", "clear": "清除選取",
"skipMetadataRefreshCount": "跳過({count} 個模型)", "skipMetadataRefreshCount": "跳過({count} 個模型)",
"resumeMetadataRefreshCount": "恢復({count} 個模型)", "resumeMetadataRefreshCount": "恢復({count} 個模型)",
@@ -808,8 +809,9 @@
"sendToWorkflowAppend": "傳送到工作流(附加)", "sendToWorkflowAppend": "傳送到工作流(附加)",
"sendToWorkflowReplace": "傳送到工作流(取代)", "sendToWorkflowReplace": "傳送到工作流(取代)",
"openExamples": "開啟範例資料夾", "openExamples": "開啟範例資料夾",
"downloadExamples": "下載缺少的範例圖片", "downloadExamples": "下載範例圖片",
"reprocessExamples": "重新處理範例圖片", "downloadMissingExamples": "下載缺少的",
"reprocessExamples": "重新處理全部",
"replacePreview": "更換預覽圖", "replacePreview": "更換預覽圖",
"setContentRating": "設定內容分級", "setContentRating": "設定內容分級",
"moveToFolder": "移動到資料夾", "moveToFolder": "移動到資料夾",

View File

@@ -137,17 +137,10 @@ export class BulkContextMenu extends BaseContextMenu {
downloadMissingLorasItem.style.display = currentModelType === 'recipes' ? 'flex' : 'none'; downloadMissingLorasItem.style.display = currentModelType === 'recipes' ? 'flex' : 'none';
} }
const downloadExampleImagesItem = this.menu.querySelector('[data-action="download-example-images"]'); const downloadExampleImagesSubmenu = this.menu.querySelector('[data-has-submenu="download-example-images"]');
if (downloadExampleImagesItem) { if (downloadExampleImagesSubmenu) {
// Show on model pages (loras, checkpoints, embeddings), hide on recipes // Show on model pages (loras, checkpoints, embeddings), hide on recipes
const modelPages = ['loras', 'checkpoints', 'embeddings']; downloadExampleImagesSubmenu.style.display = ['loras', 'checkpoints', 'embeddings'].includes(currentModelType) ? 'flex' : 'none';
downloadExampleImagesItem.style.display = modelPages.includes(currentModelType) ? 'flex' : 'none';
}
const downloadMissingExampleImagesItem = this.menu.querySelector('[data-action="download-missing-example-images"]');
if (downloadMissingExampleImagesItem) {
// Show on model pages (loras, checkpoints, embeddings), hide on recipes
downloadMissingExampleImagesItem.style.display = ['loras', 'checkpoints', 'embeddings'].includes(currentModelType) ? 'flex' : 'none';
} }
const skipMetadataRefreshItem = this.menu.querySelector('[data-action="skip-metadata-refresh"]'); const skipMetadataRefreshItem = this.menu.querySelector('[data-action="skip-metadata-refresh"]');

View File

@@ -32,8 +32,12 @@
<div class="context-menu-separator menu-section-break"></div> <div class="context-menu-separator menu-section-break"></div>
<!-- Media / Preview --> <!-- Media / Preview -->
<div class="context-menu-item" data-action="preview"><i class="fas fa-folder-open"></i> {{ t('loras.contextMenu.openExamples') }}</div> <div class="context-menu-item" data-action="preview"><i class="fas fa-folder-open"></i> {{ t('loras.contextMenu.openExamples') }}</div>
<div class="context-menu-item" data-action="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadExamples') }}</div> <div class="context-menu-item has-submenu" data-has-submenu="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadExamples') }} <i class="fas fa-chevron-right submenu-arrow"></i>
<div class="context-submenu">
<div class="context-menu-item" data-action="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadMissingExamples') }}</div>
<div class="context-menu-item" data-action="download-examples-force"><i class="fas fa-redo-alt"></i> {{ t('loras.contextMenu.reprocessExamples') }}</div> <div class="context-menu-item" data-action="download-examples-force"><i class="fas fa-redo-alt"></i> {{ t('loras.contextMenu.reprocessExamples') }}</div>
</div>
</div>
<div class="context-menu-item" data-action="replace-preview"><i class="fas fa-image"></i> {{ t('loras.contextMenu.replacePreview') }}</div> <div class="context-menu-item" data-action="replace-preview"><i class="fas fa-image"></i> {{ t('loras.contextMenu.replacePreview') }}</div>
<div class="context-menu-separator menu-section-break"></div> <div class="context-menu-separator menu-section-break"></div>
<!-- Attributes --> <!-- Attributes -->

View File

@@ -44,12 +44,19 @@
<div class="context-menu-item" data-action="preview"> <div class="context-menu-item" data-action="preview">
<i class="fas fa-folder-open"></i> <span>{{ t('loras.contextMenu.openExamples') }}</span> <i class="fas fa-folder-open"></i> <span>{{ t('loras.contextMenu.openExamples') }}</span>
</div> </div>
<div class="context-menu-item has-submenu" data-has-submenu="download-examples">
<i class="fas fa-download"></i>
<span>{{ t('loras.contextMenu.downloadExamples') }}</span>
<i class="fas fa-chevron-right submenu-arrow"></i>
<div class="context-submenu">
<div class="context-menu-item" data-action="download-examples"> <div class="context-menu-item" data-action="download-examples">
<i class="fas fa-download"></i> <span>{{ t('loras.contextMenu.downloadExamples') }}</span> <i class="fas fa-download"></i> <span>{{ t('loras.contextMenu.downloadMissingExamples') }}</span>
</div> </div>
<div class="context-menu-item" data-action="download-examples-force"> <div class="context-menu-item" data-action="download-examples-force">
<i class="fas fa-redo-alt"></i> <span>{{ t('loras.contextMenu.reprocessExamples') }}</span> <i class="fas fa-redo-alt"></i> <span>{{ t('loras.contextMenu.reprocessExamples') }}</span>
</div> </div>
</div>
</div>
<div class="context-menu-item" data-action="replace-preview"> <div class="context-menu-item" data-action="replace-preview">
<i class="fas fa-image"></i> <span>{{ t('loras.contextMenu.replacePreview') }}</span> <i class="fas fa-image"></i> <span>{{ t('loras.contextMenu.replacePreview') }}</span>
</div> </div>
@@ -139,12 +146,19 @@
</div> </div>
<div class="context-menu-section" data-section="download"> <div class="context-menu-section" data-section="download">
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.download') }}</div> <div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.download') }}</div>
<div class="context-menu-item has-submenu" data-has-submenu="download-example-images">
<i class="fas fa-download"></i>
<span>{{ t('loras.bulkOperations.downloadExamples') }}</span>
<i class="fas fa-chevron-right submenu-arrow"></i>
<div class="context-submenu">
<div class="context-menu-item" data-action="download-missing-example-images"> <div class="context-menu-item" data-action="download-missing-example-images">
<i class="fas fa-download"></i> <span>{{ t('loras.bulkOperations.downloadMissingExamples') }}</span> <i class="fas fa-download"></i> <span>{{ t('loras.bulkOperations.downloadMissingExamples') }}</span>
</div> </div>
<div class="context-menu-item" data-action="download-example-images"> <div class="context-menu-item" data-action="download-example-images">
<i class="fas fa-redo-alt"></i> <span>{{ t('loras.bulkOperations.reprocessExamples') }}</span> <i class="fas fa-redo-alt"></i> <span>{{ t('loras.bulkOperations.reprocessExamples') }}</span>
</div> </div>
</div>
</div>
<div class="context-menu-item" data-action="download-missing-loras"> <div class="context-menu-item" data-action="download-missing-loras">
<i class="fas fa-download"></i> <span>{{ t('loras.bulkOperations.downloadMissingLoras') }}</span> <i class="fas fa-download"></i> <span>{{ t('loras.bulkOperations.downloadMissingLoras') }}</span>
</div> </div>

View File

@@ -32,8 +32,12 @@
<div class="context-menu-separator menu-section-break"></div> <div class="context-menu-separator menu-section-break"></div>
<!-- Media / Preview --> <!-- Media / Preview -->
<div class="context-menu-item" data-action="preview"><i class="fas fa-folder-open"></i> {{ t('loras.contextMenu.openExamples') }}</div> <div class="context-menu-item" data-action="preview"><i class="fas fa-folder-open"></i> {{ t('loras.contextMenu.openExamples') }}</div>
<div class="context-menu-item" data-action="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadExamples') }}</div> <div class="context-menu-item has-submenu" data-has-submenu="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadExamples') }} <i class="fas fa-chevron-right submenu-arrow"></i>
<div class="context-submenu">
<div class="context-menu-item" data-action="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadMissingExamples') }}</div>
<div class="context-menu-item" data-action="download-examples-force"><i class="fas fa-redo-alt"></i> {{ t('loras.contextMenu.reprocessExamples') }}</div> <div class="context-menu-item" data-action="download-examples-force"><i class="fas fa-redo-alt"></i> {{ t('loras.contextMenu.reprocessExamples') }}</div>
</div>
</div>
<div class="context-menu-item" data-action="replace-preview"><i class="fas fa-image"></i> {{ t('loras.contextMenu.replacePreview') }}</div> <div class="context-menu-item" data-action="replace-preview"><i class="fas fa-image"></i> {{ t('loras.contextMenu.replacePreview') }}</div>
<div class="context-menu-separator menu-section-break"></div> <div class="context-menu-separator menu-section-break"></div>
<!-- Attributes --> <!-- Attributes -->

View File

@@ -2159,9 +2159,13 @@ describe('Interaction-level regression coverage', () => {
it('routes single-model example downloads to missing-only and force paths', async () => { it('routes single-model example downloads to missing-only and force paths', async () => {
document.body.innerHTML = ` document.body.innerHTML = `
<div id="loraContextMenu" class="context-menu"> <div id="loraContextMenu" class="context-menu">
<div class="context-menu-item has-submenu" data-has-submenu="download-examples">
<div class="context-submenu">
<div class="context-menu-item" data-action="download-examples"></div> <div class="context-menu-item" data-action="download-examples"></div>
<div class="context-menu-item" data-action="download-examples-force"></div> <div class="context-menu-item" data-action="download-examples-force"></div>
</div> </div>
</div>
</div>
`; `;
const { LoraContextMenu } = await import('../../../static/js/components/ContextMenu/LoraContextMenu.js'); const { LoraContextMenu } = await import('../../../static/js/components/ContextMenu/LoraContextMenu.js');