diff --git a/locales/de.json b/locales/de.json index 56155d93..860602f4 100644 --- a/locales/de.json +++ b/locales/de.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "Ausgeschlossene Modelle verwalten" + }, + "groupByModel": { + "label": "Nach Modell gruppieren" } }, "header": { diff --git a/locales/en.json b/locales/en.json index 9b1d95ae..91d1f28f 100644 --- a/locales/en.json +++ b/locales/en.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "Manage Excluded Models" + }, + "groupByModel": { + "label": "Group by Model" } }, "header": { diff --git a/locales/es.json b/locales/es.json index 33a96fd2..8ea639a7 100644 --- a/locales/es.json +++ b/locales/es.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "Gestionar modelos excluidos" + }, + "groupByModel": { + "label": "Agrupar por modelo" } }, "header": { diff --git a/locales/fr.json b/locales/fr.json index e5b440c1..a53052cd 100644 --- a/locales/fr.json +++ b/locales/fr.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "Gérer les modèles exclus" + }, + "groupByModel": { + "label": "Grouper par modèle" } }, "header": { diff --git a/locales/he.json b/locales/he.json index e46a7e86..701a6f28 100644 --- a/locales/he.json +++ b/locales/he.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "ניהול מודלים מוחרגים" + }, + "groupByModel": { + "label": "קיבוץ לפי דגם" } }, "header": { diff --git a/locales/ja.json b/locales/ja.json index dec243cd..7f7f6996 100644 --- a/locales/ja.json +++ b/locales/ja.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "除外モデルを管理" + }, + "groupByModel": { + "label": "モデルでグループ化" } }, "header": { diff --git a/locales/ko.json b/locales/ko.json index d01e5544..9701ed04 100644 --- a/locales/ko.json +++ b/locales/ko.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "제외된 모델 관리" + }, + "groupByModel": { + "label": "모델별 그룹화" } }, "header": { diff --git a/locales/ru.json b/locales/ru.json index 6059b2d1..64907d45 100644 --- a/locales/ru.json +++ b/locales/ru.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "Управление исключёнными моделями" + }, + "groupByModel": { + "label": "Группировать по модели" } }, "header": { diff --git a/locales/zh-CN.json b/locales/zh-CN.json index 3b6996b9..66156f98 100644 --- a/locales/zh-CN.json +++ b/locales/zh-CN.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "管理已排除的模型" + }, + "groupByModel": { + "label": "按模型分组" } }, "header": { diff --git a/locales/zh-TW.json b/locales/zh-TW.json index 37a5b810..5ff2028d 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -183,6 +183,9 @@ }, "manageExcludedModels": { "label": "管理已排除的模型" + }, + "groupByModel": { + "label": "按模型分組" } }, "header": { diff --git a/static/js/components/ContextMenu/GlobalContextMenu.js b/static/js/components/ContextMenu/GlobalContextMenu.js index 7a0a2979..c081a926 100644 --- a/static/js/components/ContextMenu/GlobalContextMenu.js +++ b/static/js/components/ContextMenu/GlobalContextMenu.js @@ -24,6 +24,14 @@ export class GlobalContextMenu extends BaseContextMenu { const cleanupExamplesItem = this.menu.querySelector('[data-action="cleanup-example-images-folders"]'); const excludedModelsItem = this.menu.querySelector('[data-action="manage-excluded-models"]'); const repairRecipesItem = this.menu.querySelector('[data-action="repair-recipes"]'); + const groupByModelItem = this.menu.querySelector('[data-action="toggle-group-by-model"]'); + const groupByModelCheck = groupByModelItem?.querySelector('.check-indicator'); + + // Update check indicator for group-by-model + if (groupByModelCheck) { + const isEnabled = !!state.global.settings.group_by_model; + groupByModelCheck.style.display = isEnabled ? 'block' : 'none'; + } if (isRecipesPage) { modelUpdateItem?.classList.add('hidden'); @@ -31,6 +39,7 @@ export class GlobalContextMenu extends BaseContextMenu { downloadExamplesItem?.classList.add('hidden'); cleanupExamplesItem?.classList.add('hidden'); excludedModelsItem?.classList.add('hidden'); + groupByModelItem?.classList.add('hidden'); repairRecipesItem?.classList.remove('hidden'); } else { modelUpdateItem?.classList.remove('hidden'); @@ -38,6 +47,7 @@ export class GlobalContextMenu extends BaseContextMenu { downloadExamplesItem?.classList.remove('hidden'); cleanupExamplesItem?.classList.remove('hidden'); excludedModelsItem?.classList.remove('hidden'); + groupByModelItem?.classList.remove('hidden'); repairRecipesItem?.classList.add('hidden'); } @@ -74,6 +84,9 @@ export class GlobalContextMenu extends BaseContextMenu { case 'manage-excluded-models': this.manageExcludedModels(); break; + case 'toggle-group-by-model': + this.toggleGroupByModel(); + break; default: console.warn(`Unhandled global context menu action: ${action}`); break; @@ -86,6 +99,25 @@ export class GlobalContextMenu extends BaseContextMenu { }); } + toggleGroupByModel() { + const sm = window.settingsManager; + if (!sm) { + console.error('settingsManager not available on window'); + return; + } + const newValue = !state.global.settings.group_by_model; + state.global.settings.group_by_model = newValue; + + sm.saveSetting('group_by_model', newValue).catch((error) => { + console.error('Failed to save group_by_model setting:', error); + // Revert state on failure + state.global.settings.group_by_model = !newValue; + }); + + sm.applyFrontendSettings(); + sm.reloadContent(); + } + async downloadExampleImages(menuItem) { const downloadPath = state?.global?.settings?.example_images_path; if (!downloadPath) { diff --git a/templates/components/context_menu.html b/templates/components/context_menu.html index 00b85a9e..67bbdbc0 100644 --- a/templates/components/context_menu.html +++ b/templates/components/context_menu.html @@ -158,6 +158,11 @@
{{ t('globalContextMenu.manageExcludedModels.label', default='Manage Excluded Models') }}
+
+
+ {{ t('globalContextMenu.groupByModel.label') }} + +
{{ t('globalContextMenu.repairRecipes.label') }}