feat(modal): open model metadata sidecar location from the model modal

Centralized sidecar storage moves .metadata.json into a mirror tree, so
the Location link in the model modal could no longer reveal a model's
sidecar. The Location row now shows an inline metadata icon button
(centralized mode only) that calls a new
POST /api/lm/models/open-sidecar-location endpoint: the backend resolves
the sidecar through py/utils/sidecar_paths, reveals the .metadata.json
selected in the file manager (falling back to the sidecar directory when
it has not been written yet), and returns the path for clipboard mode on
headless/Docker sessions. The platform reveal logic is factored into a
shared FileSystemHandler._reveal_file helper. All 9 locales translated.
This commit is contained in:
Will Miao
2026-10-10 07:41:48 +08:00
parent 7937aeaa04
commit af90fe873d
17 changed files with 622 additions and 58 deletions
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "Auf Hugging Face ansehen",
"viewCreatorProfile": "Ersteller-Profil anzeigen",
"openFileLocation": "Dateispeicherort öffnen",
"openSidecarLocation": "Metadaten-Speicherort öffnen",
"sendToWorkflow": "An ComfyUI senden",
"sendToWorkflowText": "An ComfyUI senden",
"copyHash": "Hash kopieren",
@@ -1905,6 +1906,12 @@
"copied": "Pfad in die Zwischenablage kopiert: {{path}}",
"clipboardFallback": "Pfad: {{path}}"
},
"openSidecarLocation": {
"success": "Metadaten-Speicherort erfolgreich geöffnet",
"failed": "Fehler beim Öffnen des Metadaten-Speicherorts",
"copied": "Pfad in die Zwischenablage kopiert: {{path}}",
"clipboardFallback": "Pfad: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "Kann nicht an ComfyUI senden: Kein Dateipfad verfügbar"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "View on Hugging Face",
"viewCreatorProfile": "View Creator Profile",
"openFileLocation": "Open File Location",
"openSidecarLocation": "Open metadata location",
"sendToWorkflow": "Send to ComfyUI",
"sendToWorkflowText": "Send to ComfyUI",
"copyHash": "Copy hash",
@@ -1905,6 +1906,12 @@
"copied": "Path copied to clipboard: {{path}}",
"clipboardFallback": "Path: {{path}}"
},
"openSidecarLocation": {
"success": "Metadata location opened successfully",
"failed": "Failed to open metadata location",
"copied": "Path copied to clipboard: {{path}}",
"clipboardFallback": "Path: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "Unable to send to ComfyUI: No file path available"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "Ver en Hugging Face",
"viewCreatorProfile": "Ver perfil del creador",
"openFileLocation": "Abrir ubicación del archivo",
"openSidecarLocation": "Abrir ubicación de los metadatos",
"sendToWorkflow": "Enviar a ComfyUI",
"sendToWorkflowText": "Enviar a ComfyUI",
"copyHash": "Copiar hash",
@@ -1905,6 +1906,12 @@
"copied": "Ruta copiada al portapapeles: {{path}}",
"clipboardFallback": "Ruta: {{path}}"
},
"openSidecarLocation": {
"success": "Ubicación de los metadatos abierta exitosamente",
"failed": "Error al abrir la ubicación de los metadatos",
"copied": "Ruta copiada al portapapeles: {{path}}",
"clipboardFallback": "Ruta: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "No se puede enviar a ComfyUI: no hay ruta de archivo disponible"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "Voir sur Hugging Face",
"viewCreatorProfile": "Voir le profil du créateur",
"openFileLocation": "Ouvrir l'emplacement du fichier",
"openSidecarLocation": "Ouvrir l'emplacement des métadonnées",
"sendToWorkflow": "Envoyer vers ComfyUI",
"sendToWorkflowText": "Envoyer vers ComfyUI",
"copyHash": "Copier le hash",
@@ -1905,6 +1906,12 @@
"copied": "Chemin copié dans le presse-papiers: {{path}}",
"clipboardFallback": "Chemin: {{path}}"
},
"openSidecarLocation": {
"success": "Emplacement des métadonnées ouvert avec succès",
"failed": "Échec de l'ouverture de l'emplacement des métadonnées",
"copied": "Chemin copié dans le presse-papiers: {{path}}",
"clipboardFallback": "Chemin: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "Impossible d'envoyer vers ComfyUI : aucun chemin de fichier disponible"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "צפייה ב-Hugging Face",
"viewCreatorProfile": "הצג פרופיל יוצר",
"openFileLocation": "פתח מיקום קובץ",
"openSidecarLocation": "פתח מיקום מטא-נתונים",
"sendToWorkflow": "שלח ל-ComfyUI",
"sendToWorkflowText": "שלח ל-ComfyUI",
"copyHash": "העתק hash",
@@ -1905,6 +1906,12 @@
"copied": "הנתיב הועתק ללוח העריכה: {{path}}",
"clipboardFallback": "נתיב: {{path}}"
},
"openSidecarLocation": {
"success": "מיקום המטא-נתונים נפתח בהצלחה",
"failed": "פתיחת מיקום המטא-נתונים נכשלה",
"copied": "הנתיב הועתק ללוח העריכה: {{path}}",
"clipboardFallback": "נתיב: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "לא ניתן לשלוח ל-ComfyUI: אין נתיב קובץ זמין"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "Hugging Face で見る",
"viewCreatorProfile": "作成者プロフィールを表示",
"openFileLocation": "ファイルの場所を開く",
"openSidecarLocation": "メタデータの場所を開く",
"sendToWorkflow": "ComfyUI に送信",
"sendToWorkflowText": "ComfyUI に送信",
"copyHash": "ハッシュをコピー",
@@ -1905,6 +1906,12 @@
"copied": "パスをクリップボードにコピーしました: {{path}}",
"clipboardFallback": "パス: {{path}}"
},
"openSidecarLocation": {
"success": "メタデータの場所を正常に開きました",
"failed": "メタデータの場所を開くのに失敗しました",
"copied": "パスをクリップボードにコピーしました: {{path}}",
"clipboardFallback": "パス: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "ComfyUI に送信できません:ファイルパスがありません"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "Hugging Face에서 보기",
"viewCreatorProfile": "제작자 프로필 보기",
"openFileLocation": "파일 위치 열기",
"openSidecarLocation": "메타데이터 위치 열기",
"sendToWorkflow": "ComfyUI로 보내기",
"sendToWorkflowText": "ComfyUI로 보내기",
"copyHash": "해시 복사",
@@ -1905,6 +1906,12 @@
"copied": "경로가 클립보드에 복사되었습니다: {{path}}",
"clipboardFallback": "경로: {{path}}"
},
"openSidecarLocation": {
"success": "메타데이터 위치가 성공적으로 열렸습니다",
"failed": "메타데이터 위치 열기에 실패했습니다",
"copied": "경로가 클립보드에 복사되었습니다: {{path}}",
"clipboardFallback": "경로: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "ComfyUI로 보낼 수 없습니다: 파일 경로가 없습니다"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "Открыть Hugging Face",
"viewCreatorProfile": "Посмотреть профиль создателя",
"openFileLocation": "Открыть расположение файла",
"openSidecarLocation": "Открыть расположение метаданных",
"sendToWorkflow": "Отправить в ComfyUI",
"sendToWorkflowText": "Отправить в ComfyUI",
"copyHash": "Копировать хеш",
@@ -1905,6 +1906,12 @@
"copied": "Путь скопирован в буфер обмена: {{path}}",
"clipboardFallback": "Путь: {{path}}"
},
"openSidecarLocation": {
"success": "Расположение метаданных успешно открыто",
"failed": "Не удалось открыть расположение метаданных",
"copied": "Путь скопирован в буфер обмена: {{path}}",
"clipboardFallback": "Путь: {{path}}"
},
"sendToWorkflow": {
"noFilePath": "Невозможно отправить в ComfyUI: путь к файлу недоступен"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "在 Hugging Face 查看",
"viewCreatorProfile": "查看创作者主页",
"openFileLocation": "打开文件位置",
"openSidecarLocation": "打开元数据位置",
"sendToWorkflow": "发送到 ComfyUI",
"sendToWorkflowText": "发送到 ComfyUI",
"copyHash": "复制哈希值",
@@ -1905,6 +1906,12 @@
"copied": "路径已复制到剪贴板:{{path}}",
"clipboardFallback": "路径:{{path}}"
},
"openSidecarLocation": {
"success": "元数据位置已成功打开",
"failed": "打开元数据位置失败",
"copied": "路径已复制到剪贴板:{{path}}",
"clipboardFallback": "路径:{{path}}"
},
"sendToWorkflow": {
"noFilePath": "无法发送到 ComfyUI:没有可用的文件路径"
},
+7
View File
@@ -1892,6 +1892,7 @@
"viewOnHuggingFaceText": "在 Hugging Face 查看",
"viewCreatorProfile": "查看創作者個人檔案",
"openFileLocation": "開啟檔案位置",
"openSidecarLocation": "開啟中繼資料位置",
"sendToWorkflow": "傳送到 ComfyUI",
"sendToWorkflowText": "傳送到 ComfyUI",
"copyHash": "複製雜湊值",
@@ -1905,6 +1906,12 @@
"copied": "路徑已複製到剪貼簿:{{path}}",
"clipboardFallback": "路徑:{{path}}"
},
"openSidecarLocation": {
"success": "中繼資料位置已成功開啟",
"failed": "開啟中繼資料位置失敗",
"copied": "路徑已複製到剪貼簿:{{path}}",
"clipboardFallback": "路徑:{{path}}"
},
"sendToWorkflow": {
"noFilePath": "無法傳送到 ComfyUI:沒有可用的檔案路徑"
},