mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-06-22 11:21:15 -03:00
Compare commits
3 Commits
7cbddd9cf7
...
dd1cdce16d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd1cdce16d | ||
|
|
a9e0e7dc8d | ||
|
|
b302d1db7d |
@@ -692,6 +692,7 @@
|
||||
"copyAll": "Alle Syntax kopieren",
|
||||
"refreshAll": "Alle Metadaten aktualisieren",
|
||||
"repairMetadata": "Metadaten der Auswahl reparieren",
|
||||
"reimportMetadata": "Metadaten der Auswahl neu importieren",
|
||||
"checkUpdates": "Auswahl auf Updates prüfen",
|
||||
"moveAll": "Alle in Ordner verschieben",
|
||||
"autoOrganize": "Automatisch organisieren",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "Inhaltsbewertung festlegen",
|
||||
"moveToFolder": "In Ordner verschieben",
|
||||
"repairMetadata": "Metadaten reparieren",
|
||||
"reimportMetadata": "Aus Quelle neu importieren",
|
||||
"excludeModel": "Modell ausschließen",
|
||||
"restoreModel": "Modell wiederherstellen",
|
||||
"deleteModel": "Modell löschen",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "Rezept bereits in der neuesten Version, keine Reparatur erforderlich",
|
||||
"failed": "Rezept-Reparatur fehlgeschlagen: {message}",
|
||||
"missingId": "Rezept kann nicht repariert werden: Fehlende Rezept-ID"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "Rezept wird aus Quelle neu importiert...",
|
||||
"success": "Rezept erfolgreich neu importiert",
|
||||
"noSourceUrl": "Rezept hat keine Quell-URL, Neuimport nicht möglich",
|
||||
"failed": "Neuimport des Rezepts fehlgeschlagen: {message}",
|
||||
"missingId": "Neuimport nicht möglich: Rezept-ID fehlt"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "Reparatur abgeschlossen: {repaired} repariert, {skipped} übersprungen (von {total})",
|
||||
"repairBulkSkipped": "Keine Reparatur für die {total} ausgewählten Rezepte erforderlich",
|
||||
"repairBulkFailed": "Reparatur der ausgewählten Rezepte fehlgeschlagen: {message}",
|
||||
"reimporting": "Rezept wird aus Quelle neu importiert...",
|
||||
"reimportSuccess": "Rezept erfolgreich neu importiert",
|
||||
"reimportBulkComplete": "Neuimport abgeschlossen: {completed} importiert, {failed} fehlgeschlagen (von {total})",
|
||||
"reimportBulkFailed": "Neuimport einiger Rezepte fehlgeschlagen",
|
||||
"noMissingLorasInSelection": "Keine fehlenden LoRAs in ausgewählten Rezepten gefunden",
|
||||
"noLoraRootConfigured": "Kein LoRA-Stammverzeichnis konfiguriert. Bitte legen Sie ein Standard-LoRA-Stammverzeichnis in den Einstellungen fest."
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "Copy Selected Syntax",
|
||||
"refreshAll": "Refresh Selected Metadata",
|
||||
"repairMetadata": "Repair Metadata for Selected",
|
||||
"reimportMetadata": "Re-import Metadata for Selected",
|
||||
"checkUpdates": "Check Updates for Selected",
|
||||
"moveAll": "Move Selected to Folder",
|
||||
"autoOrganize": "Auto-Organize Selected",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "Set Content Rating",
|
||||
"moveToFolder": "Move to Folder",
|
||||
"repairMetadata": "Repair metadata",
|
||||
"reimportMetadata": "Re-import from Source",
|
||||
"excludeModel": "Exclude Model",
|
||||
"restoreModel": "Restore Model",
|
||||
"deleteModel": "Delete Model",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "Recipe already at latest version, no repair needed",
|
||||
"failed": "Failed to repair recipe: {message}",
|
||||
"missingId": "Cannot repair recipe: Missing recipe ID"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "Re-importing recipe from source...",
|
||||
"success": "Recipe re-imported successfully",
|
||||
"noSourceUrl": "Recipe has no source URL, cannot re-import",
|
||||
"failed": "Failed to re-import recipe: {message}",
|
||||
"missingId": "Cannot re-import recipe: Missing recipe ID"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "Repair complete: {repaired} repaired, {skipped} skipped (of {total})",
|
||||
"repairBulkSkipped": "No repair needed for any of the {total} selected recipes",
|
||||
"repairBulkFailed": "Failed to repair selected recipes: {message}",
|
||||
"reimporting": "Re-importing recipe from source...",
|
||||
"reimportSuccess": "Recipe re-imported successfully",
|
||||
"reimportBulkComplete": "Re-import complete: {completed} re-imported, {failed} failed (of {total})",
|
||||
"reimportBulkFailed": "Failed to re-import some recipes",
|
||||
"noMissingLorasInSelection": "No missing LoRAs found in selected recipes",
|
||||
"noLoraRootConfigured": "No LoRA root directory configured. Please set a default LoRA root in settings."
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "Copiar toda la sintaxis",
|
||||
"refreshAll": "Actualizar todos los metadatos",
|
||||
"repairMetadata": "Reparar metadatos de la selección",
|
||||
"reimportMetadata": "Reimportar metadatos de la selección",
|
||||
"checkUpdates": "Comprobar actualizaciones para la selección",
|
||||
"moveAll": "Mover todos a carpeta",
|
||||
"autoOrganize": "Auto-organizar seleccionados",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "Establecer clasificación de contenido",
|
||||
"moveToFolder": "Mover a carpeta",
|
||||
"repairMetadata": "Reparar metadatos",
|
||||
"reimportMetadata": "Reimportar desde origen",
|
||||
"excludeModel": "Excluir modelo",
|
||||
"restoreModel": "Restaurar modelo",
|
||||
"deleteModel": "Eliminar modelo",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "La receta ya está en la última versión, no se necesita reparación",
|
||||
"failed": "Error al reparar la receta: {message}",
|
||||
"missingId": "No se puede reparar la receta: falta el ID de la receta"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "Reimportando receta desde origen...",
|
||||
"success": "Receta reimportada exitosamente",
|
||||
"noSourceUrl": "La receta no tiene URL de origen, no se puede reimportar",
|
||||
"failed": "Error al reimportar la receta: {message}",
|
||||
"missingId": "No se puede reimportar la receta: falta el ID"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "Reparación completa: {repaired} reparadas, {skipped} omitidas (de {total})",
|
||||
"repairBulkSkipped": "No se necesita reparación para ninguna de las {total} recetas seleccionadas",
|
||||
"repairBulkFailed": "Error al reparar las recetas seleccionadas: {message}",
|
||||
"reimporting": "Reimportando receta desde origen...",
|
||||
"reimportSuccess": "Receta reimportada exitosamente",
|
||||
"reimportBulkComplete": "Reimportación completa: {completed} reimportadas, {failed} fallidas (de {total})",
|
||||
"reimportBulkFailed": "Error al reimportar algunas recetas",
|
||||
"noMissingLorasInSelection": "No se encontraron LoRAs faltantes en las recetas seleccionadas",
|
||||
"noLoraRootConfigured": "No se ha configurado el directorio raíz de LoRA. Por favor, establezca un directorio raíz de LoRA predeterminado en la configuración."
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "Copier toute la syntaxe",
|
||||
"refreshAll": "Actualiser toutes les métadonnées",
|
||||
"repairMetadata": "Réparer les métadonnées de la sélection",
|
||||
"reimportMetadata": "Ré-importer les métadonnées de la sélection",
|
||||
"checkUpdates": "Vérifier les mises à jour pour la sélection",
|
||||
"moveAll": "Déplacer tout vers un dossier",
|
||||
"autoOrganize": "Auto-organiser la sélection",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "Définir la classification du contenu",
|
||||
"moveToFolder": "Déplacer vers un dossier",
|
||||
"repairMetadata": "Réparer les métadonnées",
|
||||
"reimportMetadata": "Ré-importer depuis la source",
|
||||
"excludeModel": "Exclure le modèle",
|
||||
"restoreModel": "Restaurer le modèle",
|
||||
"deleteModel": "Supprimer le modèle",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "Recette déjà à la version la plus récente, aucune réparation nécessaire",
|
||||
"failed": "Échec de la réparation de la recette : {message}",
|
||||
"missingId": "Impossible de réparer la recette : ID de recette manquant"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "Ré-import de la recette depuis la source...",
|
||||
"success": "Recette ré-importée avec succès",
|
||||
"noSourceUrl": "La recette n'a pas d'URL source, ré-import impossible",
|
||||
"failed": "Échec du ré-import de la recette : {message}",
|
||||
"missingId": "Impossible de ré-importer la recette : ID de recette manquant"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "Réparation terminée : {repaired} réparée(s), {skipped} ignorée(s) (sur {total})",
|
||||
"repairBulkSkipped": "Aucune réparation nécessaire parmi les {total} recettes sélectionnées",
|
||||
"repairBulkFailed": "Échec de la réparation des recettes sélectionnées : {message}",
|
||||
"reimporting": "Ré-import de la recette depuis la source...",
|
||||
"reimportSuccess": "Recette ré-importée avec succès",
|
||||
"reimportBulkComplete": "Ré-import terminé : {completed} ré-importé(s), {failed} échec(s) (sur {total})",
|
||||
"reimportBulkFailed": "Échec du ré-import de certaines recettes",
|
||||
"noMissingLorasInSelection": "Aucun LoRA manquant trouvé dans les recettes sélectionnées",
|
||||
"noLoraRootConfigured": "Aucun répertoire racine LoRA configuré. Veuillez définir un répertoire racine LoRA par défaut dans les paramètres."
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "העתק את כל התחבירים",
|
||||
"refreshAll": "רענן את כל המטא-דאטה",
|
||||
"repairMetadata": "תקן מטא-דאטה עבור הנבחרים",
|
||||
"reimportMetadata": "ייבא מחדש מטא-דאטה עבור הנבחרים",
|
||||
"checkUpdates": "בדוק עדכונים לבחירה",
|
||||
"moveAll": "העבר הכל לתיקייה",
|
||||
"autoOrganize": "ארגן אוטומטית נבחרים",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "הגדר דירוג תוכן",
|
||||
"moveToFolder": "העבר לתיקייה",
|
||||
"repairMetadata": "תיקון מטא-דאטה",
|
||||
"reimportMetadata": "ייבא מחדש ממקור",
|
||||
"excludeModel": "החרג מודל",
|
||||
"restoreModel": "שחזור מודל",
|
||||
"deleteModel": "מחק מודל",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "המתכון כבר בגרסה העדכנית ביותר, אין צורך בתיקון",
|
||||
"failed": "תיקון המתכון נכשל: {message}",
|
||||
"missingId": "לא ניתן לתקן את המתכון: חסר מזהה מתכון"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "מייבא מתכון מחדש מהמקור...",
|
||||
"success": "המתכון יובא מחדש בהצלחה",
|
||||
"noSourceUrl": "למתכון אין כתובת מקור, לא ניתן לייבא מחדש",
|
||||
"failed": "ייבוא המתכון מחדש נכשל: {message}",
|
||||
"missingId": "לא ניתן לייבא מחדש: חסר מזהה מתכון"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "התיקון הושלם: {repaired} תוקנו, {skipped} דולגו (מתוך {total})",
|
||||
"repairBulkSkipped": "אין צורך בתיקון עבור {total} המתכונים הנבחרים",
|
||||
"repairBulkFailed": "תיקון המתכונים הנבחרים נכשל: {message}",
|
||||
"reimporting": "מייבא מתכון מחדש מהמקור...",
|
||||
"reimportSuccess": "המתכון יובא מחדש בהצלחה",
|
||||
"reimportBulkComplete": "ייבוא מחדש הושלם: {completed} יובאו, {failed} נכשלו (מתוך {total})",
|
||||
"reimportBulkFailed": "ייבוא מחדש של חלק מהמתכונים נכשל",
|
||||
"noMissingLorasInSelection": "לא נמצאו LoRAs חסרים במתכונים שנבחרו",
|
||||
"noLoraRootConfigured": "תיקיית השורש של LoRA לא מוגדרת. אנא הגדר תיקיית שורש LoRA ברירת מחדל בהגדרות."
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "すべての構文をコピー",
|
||||
"refreshAll": "すべてのメタデータを更新",
|
||||
"repairMetadata": "選択したレシピのメタデータを修復",
|
||||
"reimportMetadata": "選択したレシピを再インポート",
|
||||
"checkUpdates": "選択項目の更新を確認",
|
||||
"moveAll": "すべてをフォルダに移動",
|
||||
"autoOrganize": "自動整理を実行",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "コンテンツレーティングを設定",
|
||||
"moveToFolder": "フォルダに移動",
|
||||
"repairMetadata": "メタデータを修復",
|
||||
"reimportMetadata": "ソースから再インポート",
|
||||
"excludeModel": "モデルを除外",
|
||||
"restoreModel": "モデルを復元",
|
||||
"deleteModel": "モデルを削除",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "レシピはすでに最新バージョンです。修復は不要です",
|
||||
"failed": "レシピの修復に失敗しました: {message}",
|
||||
"missingId": "レシピを修復できません: レシピIDがありません"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "ソースからレシピを再インポート中...",
|
||||
"success": "レシピの再インポートが完了しました",
|
||||
"noSourceUrl": "レシピにソースURLがありません。再インポートできません",
|
||||
"failed": "レシピの再インポートに失敗しました: {message}",
|
||||
"missingId": "レシピを再インポートできません: レシピIDがありません"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "修復完了:{repaired} 件修復、{skipped} 件スキップ(合計 {total} 件)",
|
||||
"repairBulkSkipped": "選択した {total} 件のレシピは修復不要です",
|
||||
"repairBulkFailed": "選択したレシピの修復に失敗しました:{message}",
|
||||
"reimporting": "ソースからレシピを再インポート中...",
|
||||
"reimportSuccess": "レシピの再インポートが完了しました",
|
||||
"reimportBulkComplete": "再インポート完了:{completed} 件成功、{failed} 件失敗(合計 {total} 件)",
|
||||
"reimportBulkFailed": "一部のレシピの再インポートに失敗しました",
|
||||
"noMissingLorasInSelection": "選択したレシピに不足している LoRA が見つかりませんでした",
|
||||
"noLoraRootConfigured": "LoRA ルートディレクトリが設定されていません。設定でデフォルトの LoRA ルートを設定してください。"
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "모든 문법 복사",
|
||||
"refreshAll": "모든 메타데이터 새로고침",
|
||||
"repairMetadata": "선택한 레시피 메타데이터 복구",
|
||||
"reimportMetadata": "선택한 레시피 다시 가져오기",
|
||||
"checkUpdates": "선택 항목 업데이트 확인",
|
||||
"moveAll": "모두 폴더로 이동",
|
||||
"autoOrganize": "자동 정리 선택",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "콘텐츠 등급 설정",
|
||||
"moveToFolder": "폴더로 이동",
|
||||
"repairMetadata": "메타데이터 복구",
|
||||
"reimportMetadata": "소스에서 다시 가져오기",
|
||||
"excludeModel": "모델 제외",
|
||||
"restoreModel": "모델 복원",
|
||||
"deleteModel": "모델 삭제",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "레시피가 이미 최신 버전입니다. 복구가 필요하지 않습니다",
|
||||
"failed": "레시피 복구 실패: {message}",
|
||||
"missingId": "레시피를 복구할 수 없음: 레시피 ID 누락"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "소스에서 레시피를 다시 가져오는 중...",
|
||||
"success": "레시피를 다시 가져왔습니다",
|
||||
"noSourceUrl": "레시피에 소스 URL이 없어 다시 가져올 수 없습니다",
|
||||
"failed": "레시피 다시 가져오기 실패: {message}",
|
||||
"missingId": "레시피를 다시 가져올 수 없음: 레시피 ID 누락"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "복구 완료: {repaired}개 복구, {skipped}개 건너뜀 (총 {total}개)",
|
||||
"repairBulkSkipped": "선택한 {total}개 레시피는 복구가 필요하지 않습니다",
|
||||
"repairBulkFailed": "선택한 레시피 복구 실패: {message}",
|
||||
"reimporting": "소스에서 레시피를 다시 가져오는 중...",
|
||||
"reimportSuccess": "레시피를 다시 가져왔습니다",
|
||||
"reimportBulkComplete": "다시 가져오기 완료: {completed}개 성공, {failed}개 실패 (총 {total}개)",
|
||||
"reimportBulkFailed": "일부 레시피를 다시 가져오지 못했습니다",
|
||||
"noMissingLorasInSelection": "선택한 레시피에서 누락된 LoRA를 찾을 수 없습니다",
|
||||
"noLoraRootConfigured": "LoRA 루트 디렉토리가 구성되지 않았습니다. 설정에서 기본 LoRA 루트를 설정하세요."
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "Копировать весь синтаксис",
|
||||
"refreshAll": "Обновить все метаданные",
|
||||
"repairMetadata": "Восстановить метаданные для выбранных",
|
||||
"reimportMetadata": "Переимпортировать метаданные для выбранных",
|
||||
"checkUpdates": "Проверить обновления для выбранных",
|
||||
"moveAll": "Переместить все в папку",
|
||||
"autoOrganize": "Автоматически организовать выбранные",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "Установить рейтинг контента",
|
||||
"moveToFolder": "Переместить в папку",
|
||||
"repairMetadata": "Восстановить метаданные",
|
||||
"reimportMetadata": "Переимпортировать из источника",
|
||||
"excludeModel": "Исключить модель",
|
||||
"restoreModel": "Восстановить модель",
|
||||
"deleteModel": "Удалить модель",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "Рецепт уже последней версии, восстановление не требуется",
|
||||
"failed": "Не удалось восстановить рецепт: {message}",
|
||||
"missingId": "Не удалось восстановить рецепт: отсутствует ID рецепта"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "Переимпорт рецепта из источника...",
|
||||
"success": "Рецепт успешно переимпортирован",
|
||||
"noSourceUrl": "У рецепта нет URL источника, переимпорт невозможен",
|
||||
"failed": "Не удалось переимпортировать рецепт: {message}",
|
||||
"missingId": "Невозможно переимпортировать рецепт: отсутствует ID"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "Восстановление завершено: {repaired} восстановлено, {skipped} пропущено (из {total})",
|
||||
"repairBulkSkipped": "Ни один из {total} выбранных рецептов не требует восстановления",
|
||||
"repairBulkFailed": "Не удалось восстановить выбранные рецепты: {message}",
|
||||
"reimporting": "Переимпорт рецепта из источника...",
|
||||
"reimportSuccess": "Рецепт успешно переимпортирован",
|
||||
"reimportBulkComplete": "Переимпорт завершён: {completed} переимпортировано, {failed} ошибок (из {total})",
|
||||
"reimportBulkFailed": "Не удалось переимпортировать некоторые рецепты",
|
||||
"noMissingLorasInSelection": "В выбранных рецептах не найдены отсутствующие LoRAs",
|
||||
"noLoraRootConfigured": "Корневой каталог LoRA не настроен. Пожалуйста, установите корневой каталог LoRA по умолчанию в настройках."
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "复制所选中语法",
|
||||
"refreshAll": "刷新所选中元数据",
|
||||
"repairMetadata": "修复所选中元数据",
|
||||
"reimportMetadata": "重新导入所选配方元数据",
|
||||
"checkUpdates": "检查所选更新",
|
||||
"moveAll": "移动所选中到文件夹",
|
||||
"autoOrganize": "自动整理所选模型",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "设置内容评级",
|
||||
"moveToFolder": "移动到文件夹",
|
||||
"repairMetadata": "修复元数据",
|
||||
"reimportMetadata": "从源重新导入",
|
||||
"excludeModel": "排除模型",
|
||||
"restoreModel": "恢复模型",
|
||||
"deleteModel": "删除模型",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "配方已是最新版本,无需修复",
|
||||
"failed": "修复配方失败:{message}",
|
||||
"missingId": "无法修复配方:缺少配方 ID"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "正在从源重新导入配方...",
|
||||
"success": "配方已从源重新导入成功",
|
||||
"noSourceUrl": "配方没有源URL,无法重新导入",
|
||||
"failed": "重新导入配方失败:{message}",
|
||||
"missingId": "无法重新导入配方:缺少配方ID"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "修复完成:{repaired} 个已修复,{skipped} 个已跳过(共 {total} 个)",
|
||||
"repairBulkSkipped": "所选 {total} 个配方无需修复",
|
||||
"repairBulkFailed": "修复所选配方失败:{message}",
|
||||
"reimporting": "正在从源重新导入配方...",
|
||||
"reimportSuccess": "配方已从源重新导入成功",
|
||||
"reimportBulkComplete": "重新导入完成:{completed} 个已导入,{failed} 个失败(共 {total} 个)",
|
||||
"reimportBulkFailed": "重新导入某些配方失败",
|
||||
"noMissingLorasInSelection": "在选定的配方中未找到缺失的 LoRAs",
|
||||
"noLoraRootConfigured": "未配置 LoRA 根目录。请在设置中设置默认的 LoRA 根目录。"
|
||||
},
|
||||
|
||||
@@ -692,6 +692,7 @@
|
||||
"copyAll": "複製全部語法",
|
||||
"refreshAll": "刷新全部 metadata",
|
||||
"repairMetadata": "修復所選中元數據",
|
||||
"reimportMetadata": "重新匯入所選配方元數據",
|
||||
"checkUpdates": "檢查所選更新",
|
||||
"moveAll": "全部移動到資料夾",
|
||||
"autoOrganize": "自動整理所選模型",
|
||||
@@ -739,6 +740,7 @@
|
||||
"setContentRating": "設定內容分級",
|
||||
"moveToFolder": "移動到資料夾",
|
||||
"repairMetadata": "修復元數據",
|
||||
"reimportMetadata": "從來源重新匯入",
|
||||
"excludeModel": "排除模型",
|
||||
"restoreModel": "還原模型",
|
||||
"deleteModel": "刪除模型",
|
||||
@@ -866,6 +868,13 @@
|
||||
"skipped": "配方已是最新版本,無需修復",
|
||||
"failed": "修復配方失敗:{message}",
|
||||
"missingId": "無法修復配方:缺少配方 ID"
|
||||
},
|
||||
"reimport": {
|
||||
"starting": "正在從來源重新匯入配方...",
|
||||
"success": "配方已從來源重新匯入成功",
|
||||
"noSourceUrl": "配方沒有來源URL,無法重新匯入",
|
||||
"failed": "重新匯入配方失敗:{message}",
|
||||
"missingId": "無法重新匯入配方:缺少配方ID"
|
||||
}
|
||||
},
|
||||
"batchImport": {
|
||||
@@ -1717,6 +1726,10 @@
|
||||
"repairBulkComplete": "修復完成:{repaired} 個已修復,{skipped} 個已跳過(共 {total} 個)",
|
||||
"repairBulkSkipped": "所選 {total} 個配方無需修復",
|
||||
"repairBulkFailed": "修復所選配方失敗:{message}",
|
||||
"reimporting": "正在從來源重新匯入配方...",
|
||||
"reimportSuccess": "配方已從來源重新匯入成功",
|
||||
"reimportBulkComplete": "重新匯入完成:{completed} 個已匯入,{failed} 個失敗(共 {total} 個)",
|
||||
"reimportBulkFailed": "重新匯入某些配方失敗",
|
||||
"noMissingLorasInSelection": "在選取的食譜中未找到缺失的 LoRAs",
|
||||
"noLoraRootConfigured": "未配置 LoRA 根目錄。請在設定中設定預設的 LoRA 根目錄。"
|
||||
},
|
||||
|
||||
@@ -102,6 +102,7 @@ class RecipeHandlerSet:
|
||||
"check_image_exists": self.management.check_image_exists,
|
||||
"import_from_url": self.management.import_from_url,
|
||||
"create_from_example": self.management.create_from_example,
|
||||
"reimport_recipe": self.management.reimport_recipe,
|
||||
}
|
||||
|
||||
|
||||
@@ -799,6 +800,116 @@ class RecipeManagementHandler:
|
||||
self._logger.error("Error repairing single recipe: %s", exc, exc_info=True)
|
||||
return web.json_response({"success": False, "error": str(exc)}, status=500)
|
||||
|
||||
async def reimport_recipe(self, request: web.Request) -> web.Response:
|
||||
"""Delete a recipe and re-import it from its source URL.
|
||||
|
||||
This gives the recipe a fresh start — re-downloads the image from
|
||||
CivitAI, re-parses EXIF metadata with the current parser, and
|
||||
re-resolves LoRAs / checkpoint. User edits (title, tags, favorite)
|
||||
are carried over from the old recipe.
|
||||
"""
|
||||
try:
|
||||
await self._ensure_dependencies_ready()
|
||||
recipe_scanner = self._recipe_scanner_getter()
|
||||
if recipe_scanner is None:
|
||||
raise RuntimeError("Recipe scanner unavailable")
|
||||
|
||||
recipe_id = request.match_info["recipe_id"]
|
||||
old_recipe = await recipe_scanner.get_recipe_by_id(recipe_id)
|
||||
if not old_recipe:
|
||||
raise RecipeNotFoundError(f"Recipe {recipe_id} not found")
|
||||
|
||||
source_path = old_recipe.get("source_path")
|
||||
if not source_path:
|
||||
return web.json_response(
|
||||
{
|
||||
"success": False,
|
||||
"error": (
|
||||
"Recipe has no source URL — cannot re-import. "
|
||||
"Use repair or manual import instead."
|
||||
),
|
||||
},
|
||||
status=400,
|
||||
)
|
||||
|
||||
user_edits: dict[str, Any] = {}
|
||||
for key in ("title", "tags", "favorite"):
|
||||
if key in old_recipe and old_recipe[key]:
|
||||
user_edits[key] = old_recipe[key]
|
||||
if "tags" in user_edits and not isinstance(user_edits["tags"], list):
|
||||
del user_edits["tags"]
|
||||
|
||||
old_created = old_recipe.get("created_date")
|
||||
old_modified = old_recipe.get("modified")
|
||||
|
||||
await self._persistence_service.delete_recipe(
|
||||
recipe_scanner=recipe_scanner, recipe_id=recipe_id
|
||||
)
|
||||
|
||||
async with self._import_semaphore:
|
||||
import_response = await self._do_import_from_url(
|
||||
source_path, recipe_scanner
|
||||
)
|
||||
|
||||
body_bytes = import_response.body
|
||||
if not body_bytes:
|
||||
raise RuntimeError("Re-import returned an empty response")
|
||||
import_body = json.loads(body_bytes.decode())
|
||||
new_recipe_id = import_body.get("recipe_id")
|
||||
|
||||
if new_recipe_id and user_edits:
|
||||
try:
|
||||
await self._persistence_service.update_recipe(
|
||||
recipe_scanner=recipe_scanner,
|
||||
recipe_id=new_recipe_id,
|
||||
updates=user_edits,
|
||||
)
|
||||
except Exception as exc:
|
||||
self._logger.warning(
|
||||
"Re-import succeeded but failed to carry over "
|
||||
"user edits for new recipe %s: %s",
|
||||
new_recipe_id,
|
||||
exc,
|
||||
)
|
||||
|
||||
timestamp_updates: dict[str, Any] = {}
|
||||
if old_created is not None:
|
||||
timestamp_updates["created_date"] = old_created
|
||||
if old_modified is not None:
|
||||
timestamp_updates["modified"] = old_modified
|
||||
if new_recipe_id and timestamp_updates:
|
||||
try:
|
||||
await recipe_scanner.update_recipe_metadata(
|
||||
new_recipe_id, timestamp_updates
|
||||
)
|
||||
except Exception as exc:
|
||||
self._logger.warning(
|
||||
"Re-import succeeded but failed to preserve "
|
||||
"timestamps for new recipe %s: %s",
|
||||
new_recipe_id,
|
||||
exc,
|
||||
)
|
||||
|
||||
return web.json_response(
|
||||
{
|
||||
"success": True,
|
||||
"old_recipe_id": recipe_id,
|
||||
"recipe_id": new_recipe_id,
|
||||
"source_path": source_path,
|
||||
}
|
||||
)
|
||||
except RecipeNotFoundError as exc:
|
||||
return web.json_response({"success": False, "error": str(exc)}, status=404)
|
||||
except RecipeValidationError as exc:
|
||||
return web.json_response({"success": False, "error": str(exc)}, status=400)
|
||||
except RecipeDownloadError as exc:
|
||||
return web.json_response({"success": False, "error": str(exc)}, status=400)
|
||||
except Exception as exc:
|
||||
self._logger.error(
|
||||
"Error reimporting recipe: %s", exc, exc_info=True
|
||||
)
|
||||
return web.json_response({"success": False, "error": str(exc)}, status=500)
|
||||
|
||||
async def get_repair_progress(self, request: web.Request) -> web.Response:
|
||||
try:
|
||||
progress = self._ws_manager.get_recipe_repair_progress()
|
||||
|
||||
@@ -78,6 +78,9 @@ ROUTE_DEFINITIONS: tuple[RouteDefinition, ...] = (
|
||||
RouteDefinition(
|
||||
"POST", "/api/lm/recipes/create-from-example", "create_from_example"
|
||||
),
|
||||
RouteDefinition(
|
||||
"POST", "/api/lm/recipe/{recipe_id}/reimport", "reimport_recipe"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
/* Lighter separator between category groups (vs the full separator before destructive) */
|
||||
.context-menu-separator.menu-section-break {
|
||||
opacity: 0.4;
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
||||
.context-menu-item.delete-item {
|
||||
color: var(--danger-color);
|
||||
}
|
||||
|
||||
@@ -42,10 +42,14 @@ export class BulkContextMenu extends BaseContextMenu {
|
||||
const deleteAllItem = this.menu.querySelector('[data-action="delete-all"]');
|
||||
const downloadMissingLorasItem = this.menu.querySelector('[data-action="download-missing-loras"]');
|
||||
const repairMetadataItem = this.menu.querySelector('[data-action="repair-metadata"]');
|
||||
const reimportMetadataItem = this.menu.querySelector('[data-action="reimport-metadata"]');
|
||||
|
||||
if (repairMetadataItem) {
|
||||
repairMetadataItem.style.display = config.repairMetadata ? 'flex' : 'none';
|
||||
}
|
||||
if (reimportMetadataItem) {
|
||||
reimportMetadataItem.style.display = config.reimportMetadata ? 'flex' : 'none';
|
||||
}
|
||||
|
||||
if (sendToWorkflowAppendItem) {
|
||||
sendToWorkflowAppendItem.style.display = config.sendToWorkflow ? 'flex' : 'none';
|
||||
@@ -264,6 +268,9 @@ export class BulkContextMenu extends BaseContextMenu {
|
||||
case 'repair-metadata':
|
||||
bulkManager.repairSelectedRecipes();
|
||||
break;
|
||||
case 'reimport-metadata':
|
||||
bulkManager.reimportSelectedRecipes();
|
||||
break;
|
||||
case 'set-favorite': {
|
||||
const allFavorited = this.countFavoritedInSelection() === state.selectedModels.size;
|
||||
bulkManager.setBulkFavorites(!allFavorited);
|
||||
|
||||
@@ -97,6 +97,9 @@ export class RecipeContextMenu extends BaseContextMenu {
|
||||
// Repair recipe metadata
|
||||
this.repairRecipe(recipeId);
|
||||
break;
|
||||
case 'reimport':
|
||||
this.reimportRecipe(recipeId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +328,35 @@ export class RecipeContextMenu extends BaseContextMenu {
|
||||
showToast('recipes.contextMenu.repair.failed', { message: error.message }, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async reimportRecipe(recipeId) {
|
||||
if (!recipeId) {
|
||||
showToast('recipes.contextMenu.reimport.missingId', {}, 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
state.loadingManager.showSimpleLoading('Re-importing recipe from source...');
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/lm/recipe/${recipeId}/reimport`, {
|
||||
method: 'POST'
|
||||
});
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
state.loadingManager.hide();
|
||||
showToast('toast.recipes.reimportSuccess', {}, 'success');
|
||||
const { resetAndReload } = await import('../../api/recipeApi.js');
|
||||
resetAndReload(false, { preserveScroll: true });
|
||||
} else {
|
||||
throw new Error(result.error || 'Re-import failed');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error reimporting recipe:', error);
|
||||
state.loadingManager.hide();
|
||||
showToast('recipes.contextMenu.reimport.failed', { message: error.message }, 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mix in shared methods from ModelContextMenuMixin
|
||||
|
||||
@@ -86,7 +86,8 @@ export class BulkManager {
|
||||
skipMetadataRefresh: false,
|
||||
setFavorite: true,
|
||||
unfavorite: true,
|
||||
repairMetadata: true
|
||||
repairMetadata: true,
|
||||
reimportMetadata: true
|
||||
}
|
||||
};
|
||||
|
||||
@@ -657,6 +658,87 @@ export class BulkManager {
|
||||
}
|
||||
}
|
||||
|
||||
async reimportSelectedRecipes() {
|
||||
if (state.selectedModels.size === 0) {
|
||||
showToast('toast.recipes.noRecipesSelected', {}, 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.currentPageType !== 'recipes') {
|
||||
showToast('This operation is only available for recipes', {}, 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
const filePaths = Array.from(state.selectedModels);
|
||||
const total = filePaths.length;
|
||||
let completed = 0;
|
||||
let failed = 0;
|
||||
|
||||
const recipeMap = new Map();
|
||||
if (state.virtualScroller?.items) {
|
||||
for (const item of state.virtualScroller.items) {
|
||||
if (item.file_path && item.id) {
|
||||
recipeMap.set(item.file_path, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const progressUI = state.loadingManager.showEnhancedProgress(
|
||||
`Re-importing recipe 1/${total}...`
|
||||
);
|
||||
|
||||
try {
|
||||
for (let i = 0; i < filePaths.length; i++) {
|
||||
const filePath = filePaths[i];
|
||||
const recipeItem = recipeMap.get(filePath);
|
||||
const recipeId = recipeItem?.id;
|
||||
const recipeName = recipeItem?.title || recipeId || 'Unknown';
|
||||
|
||||
progressUI.updateProgress(
|
||||
Math.floor((i / total) * 100),
|
||||
recipeName,
|
||||
`Re-importing recipe ${Math.min(i + 1, total)}/${total}...`
|
||||
);
|
||||
|
||||
if (!recipeId) {
|
||||
failed++;
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/lm/recipe/${recipeId}/reimport`,
|
||||
{ method: 'POST' }
|
||||
);
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
completed++;
|
||||
} else {
|
||||
failed++;
|
||||
}
|
||||
} catch {
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
if (completed > 0) {
|
||||
await progressUI.complete(
|
||||
`Re-import complete: ${completed} re-imported, ${failed} failed`
|
||||
);
|
||||
} else {
|
||||
state.loadingManager.hide();
|
||||
showToast('toast.recipes.reimportBulkFailed', {}, 'error');
|
||||
}
|
||||
|
||||
const { resetAndReload: recipeResetAndReload } = await import('../api/recipeApi.js');
|
||||
recipeResetAndReload(false, { preserveScroll: true });
|
||||
this.clearSelection();
|
||||
} catch (error) {
|
||||
console.error('[reimportSelectedRecipes] outer catch:', error);
|
||||
state.loadingManager.hide();
|
||||
showToast('toast.recipes.reimportBulkFailed', {}, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async repairSelectedRecipes() {
|
||||
if (state.selectedModels.size === 0) {
|
||||
showToast('toast.recipes.noRecipesSelected', {}, 'warning');
|
||||
|
||||
@@ -10,17 +10,27 @@
|
||||
{% block additional_components %}
|
||||
|
||||
<div id="checkpointContextMenu" class="context-menu" style="display: none;">
|
||||
<!-- Metadata -->
|
||||
<div class="context-menu-item" data-action="refresh-metadata"><i class="fas fa-sync"></i> {{ t('loras.contextMenu.refreshMetadata') }}</div>
|
||||
<div class="context-menu-item" data-action="relink-civitai"><i class="fas fa-link"></i> {{ t('loras.contextMenu.relinkCivitai') }}</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Workflow -->
|
||||
<div class="context-menu-item" data-action="copyname"><i class="fas fa-copy"></i> {{ t('loras.contextMenu.copyFilename') }}</div>
|
||||
<div class="context-menu-item" data-action="sendworkflow"><i class="fas fa-paper-plane"></i> {{ t('checkpoints.contextMenu.sendToWorkflow') }}</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- 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="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadExamples') }}</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>
|
||||
<!-- Attributes -->
|
||||
<div class="context-menu-item" data-action="set-nsfw"><i class="fas fa-exclamation-triangle"></i> {{ t('loras.contextMenu.setContentRating') }}</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Organization -->
|
||||
<div class="context-menu-item" data-action="move"><i class="fas fa-folder-open"></i> {{ t('loras.contextMenu.moveToFolder') }}</div>
|
||||
<div class="context-menu-item" data-action="move-other"><i class="fas fa-exchange-alt"></i> {{ t('checkpoints.contextMenu.moveToOtherTypeFolder', {otherType: '...'}) }}</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<!-- Destructive -->
|
||||
<div class="context-menu-item" data-action="exclude"><i class="fas fa-eye-slash"></i> {{ t('loras.contextMenu.excludeModel') }}</div>
|
||||
<div class="context-menu-item delete-item" data-action="delete"><i class="fas fa-trash"></i> {{ t('loras.contextMenu.deleteModel') }}</div>
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<!-- <div class="context-menu-item" data-action="civitai">
|
||||
<i class="fas fa-external-link-alt"></i> View on Civitai
|
||||
</div> -->
|
||||
<!-- Metadata -->
|
||||
<div class="context-menu-item" data-action="refresh-metadata">
|
||||
<i class="fas fa-sync"></i> <span>{{ t('loras.contextMenu.refreshMetadata') }}</span>
|
||||
</div>
|
||||
@@ -14,6 +15,8 @@
|
||||
<div class="context-menu-item" data-action="relink-civitai">
|
||||
<i class="fas fa-link"></i> <span>{{ t('loras.contextMenu.relinkCivitai') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Workflow -->
|
||||
<div class="context-menu-item" data-action="copyname">
|
||||
<i class="fas fa-copy"></i> <span>{{ t('loras.contextMenu.copySyntax') }}</span>
|
||||
</div>
|
||||
@@ -23,6 +26,8 @@
|
||||
<div class="context-menu-item" data-action="sendreplace">
|
||||
<i class="fas fa-exchange-alt"></i> <span>{{ t('loras.contextMenu.sendToWorkflowReplace') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Media / Preview -->
|
||||
<div class="context-menu-item" data-action="preview">
|
||||
<i class="fas fa-folder-open"></i> <span>{{ t('loras.contextMenu.openExamples') }}</span>
|
||||
</div>
|
||||
@@ -32,13 +37,18 @@
|
||||
<div class="context-menu-item" data-action="replace-preview">
|
||||
<i class="fas fa-image"></i> <span>{{ t('loras.contextMenu.replacePreview') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Attributes -->
|
||||
<div class="context-menu-item" data-action="set-nsfw">
|
||||
<i class="fas fa-exclamation-triangle"></i> <span>{{ t('loras.contextMenu.setContentRating') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Organization -->
|
||||
<div class="context-menu-item" data-action="move">
|
||||
<i class="fas fa-folder-open"></i> <span>{{ t('loras.contextMenu.moveToFolder') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<!-- Destructive -->
|
||||
<div class="context-menu-item" data-action="exclude">
|
||||
<i class="fas fa-eye-slash"></i> <span>{{ t('loras.contextMenu.excludeModel') }}</span>
|
||||
</div>
|
||||
@@ -53,6 +63,27 @@
|
||||
<span>{{ t('loras.bulkOperations.selected', {'count': 0}) }}</span>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-section" data-section="metadata">
|
||||
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.metadata') }}</div>
|
||||
<div class="context-menu-item" data-action="refresh-all">
|
||||
<i class="fas fa-sync-alt"></i> <span>{{ t('loras.bulkOperations.refreshAll') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="check-updates">
|
||||
<i class="fas fa-bell"></i> <span>{{ t('loras.bulkOperations.checkUpdates') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="repair-metadata">
|
||||
<i class="fas fa-tools"></i> <span>{{ t('loras.bulkOperations.repairMetadata') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="reimport-metadata">
|
||||
<i class="fas fa-undo-alt"></i> <span>{{ t('loras.bulkOperations.reimportMetadata') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="skip-metadata-refresh">
|
||||
<i class="fas fa-ban"></i> <span>{{ t('loras.bulkOperations.skipMetadataRefresh') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="resume-metadata-refresh">
|
||||
<i class="fas fa-redo"></i> <span>{{ t('loras.bulkOperations.resumeMetadataRefresh') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-section" data-section="workflow">
|
||||
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.workflow') }}</div>
|
||||
<div class="context-menu-item has-submenu" data-has-submenu="send-to-workflow">
|
||||
@@ -72,24 +103,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-section" data-section="metadata">
|
||||
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.metadata') }}</div>
|
||||
<div class="context-menu-item" data-action="refresh-all">
|
||||
<i class="fas fa-sync-alt"></i> <span>{{ t('loras.bulkOperations.refreshAll') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="check-updates">
|
||||
<i class="fas fa-bell"></i> <span>{{ t('loras.bulkOperations.checkUpdates') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="repair-metadata">
|
||||
<i class="fas fa-tools"></i> <span>{{ t('loras.bulkOperations.repairMetadata') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="skip-metadata-refresh">
|
||||
<i class="fas fa-ban"></i> <span>{{ t('loras.bulkOperations.skipMetadataRefresh') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="resume-metadata-refresh">
|
||||
<i class="fas fa-redo"></i> <span>{{ t('loras.bulkOperations.resumeMetadataRefresh') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-section" data-section="attributes">
|
||||
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.attributes') }}</div>
|
||||
<div class="context-menu-item" data-action="add-tags">
|
||||
@@ -105,15 +118,6 @@
|
||||
<i class="fas fa-exclamation-triangle"></i> <span>{{ t('loras.bulkOperations.setContentRating') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-section" data-section="organize">
|
||||
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.organize') }}</div>
|
||||
<div class="context-menu-item" data-action="auto-organize">
|
||||
<i class="fas fa-magic"></i> <span>{{ t('loras.bulkOperations.autoOrganize') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="move-all">
|
||||
<i class="fas fa-folder-open"></i> <span>{{ t('loras.bulkOperations.moveAll') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-section" data-section="download">
|
||||
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.download') }}</div>
|
||||
<div class="context-menu-item" data-action="download-example-images">
|
||||
@@ -123,6 +127,15 @@
|
||||
<i class="fas fa-download"></i> <span>{{ t('loras.bulkOperations.downloadMissingLoras') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-section" data-section="organize">
|
||||
<div class="context-menu-section-header">{{ t('loras.bulkOperations.sections.organize') }}</div>
|
||||
<div class="context-menu-item" data-action="auto-organize">
|
||||
<i class="fas fa-magic"></i> <span>{{ t('loras.bulkOperations.autoOrganize') }}</span>
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="move-all">
|
||||
<i class="fas fa-folder-open"></i> <span>{{ t('loras.bulkOperations.moveAll') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-item delete-item" data-action="delete-all">
|
||||
<i class="fas fa-trash"></i> <span>{{ t('loras.bulkOperations.deleteAll') }}</span>
|
||||
|
||||
@@ -10,15 +10,25 @@
|
||||
{% block additional_components %}
|
||||
|
||||
<div id="embeddingContextMenu" class="context-menu" style="display: none;">
|
||||
<!-- Metadata -->
|
||||
<div class="context-menu-item" data-action="refresh-metadata"><i class="fas fa-sync"></i> {{ t('loras.contextMenu.refreshMetadata') }}</div>
|
||||
<div class="context-menu-item" data-action="relink-civitai"><i class="fas fa-link"></i> {{ t('loras.contextMenu.relinkCivitai') }}</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Workflow -->
|
||||
<div class="context-menu-item" data-action="copyname"><i class="fas fa-copy"></i> {{ t('loras.contextMenu.copyFilename') }}</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- 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="download-examples"><i class="fas fa-download"></i> {{ t('loras.contextMenu.downloadExamples') }}</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>
|
||||
<!-- Attributes -->
|
||||
<div class="context-menu-item" data-action="set-nsfw"><i class="fas fa-exclamation-triangle"></i> {{ t('loras.contextMenu.setContentRating') }}</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Organization -->
|
||||
<div class="context-menu-item" data-action="move"><i class="fas fa-folder-open"></i> {{ t('loras.contextMenu.moveToFolder') }}</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<!-- Destructive -->
|
||||
<div class="context-menu-item" data-action="exclude"><i class="fas fa-eye-slash"></i> {{ t('loras.contextMenu.excludeModel') }}</div>
|
||||
<div class="context-menu-item delete-item" data-action="delete"><i class="fas fa-trash"></i> {{ t('loras.contextMenu.deleteModel') }}</div>
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,15 @@
|
||||
|
||||
<div id="recipeContextMenu" class="context-menu" style="display: none;">
|
||||
<!-- <div class="context-menu-item" data-action="details"><i class="fas fa-info-circle"></i> View Details</div> -->
|
||||
<!-- Metadata -->
|
||||
<div class="context-menu-item" data-action="repair">
|
||||
<i class="fas fa-tools"></i> {{ t('loras.contextMenu.repairMetadata') }}
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="reimport">
|
||||
<i class="fas fa-undo-alt"></i> {{ t('loras.contextMenu.reimportMetadata') }}
|
||||
</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Workflow / Share -->
|
||||
<div class="context-menu-item" data-action="share"><i class="fas fa-share-alt"></i> {{
|
||||
t('loras.contextMenu.shareRecipe') }}</div>
|
||||
<div class="context-menu-item" data-action="copy"><i class="fas fa-copy"></i> {{
|
||||
@@ -25,19 +34,23 @@
|
||||
t('loras.contextMenu.sendToWorkflowAppend') }}</div>
|
||||
<div class="context-menu-item" data-action="sendreplace"><i class="fas fa-exchange-alt"></i> {{
|
||||
t('loras.contextMenu.sendToWorkflowReplace') }}</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Recipe-specific -->
|
||||
<div class="context-menu-item" data-action="viewloras"><i class="fas fa-layer-group"></i> {{
|
||||
t('loras.contextMenu.viewAllLoras') }}</div>
|
||||
<div class="context-menu-item download-missing-item" data-action="download-missing"><i class="fas fa-download"></i>
|
||||
{{ t('loras.contextMenu.downloadMissingLoras') }}</div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Attributes -->
|
||||
<div class="context-menu-item" data-action="set-nsfw">
|
||||
<i class="fas fa-exclamation-triangle"></i> {{ t('loras.contextMenu.setContentRating') }}
|
||||
</div>
|
||||
<div class="context-menu-item" data-action="repair">
|
||||
<i class="fas fa-tools"></i> {{ t('loras.contextMenu.repairMetadata') }}
|
||||
</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<div class="context-menu-separator menu-section-break"></div>
|
||||
<!-- Organization -->
|
||||
<div class="context-menu-item" data-action="move"><i class="fas fa-folder-open"></i> {{
|
||||
t('loras.contextMenu.moveToFolder') }}</div>
|
||||
<div class="context-menu-separator"></div>
|
||||
<!-- Destructive -->
|
||||
<div class="context-menu-item delete-item" data-action="delete"><i class="fas fa-trash"></i> {{
|
||||
t('loras.contextMenu.deleteRecipe') }}</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user