mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-03-21 21:22:11 -03:00
feat(sidebar): add recursive search functionality and toggle button
This commit is contained in:
@@ -529,12 +529,15 @@
|
||||
"title": "Embedding-Modelle"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "Modell-Stammverzeichnis",
|
||||
"modelRoot": "Stammverzeichnis",
|
||||
"collapseAll": "Alle Ordner einklappen",
|
||||
"pinSidebar": "Sidebar anheften",
|
||||
"unpinSidebar": "Sidebar lösen",
|
||||
"switchToListView": "Zur Listenansicht wechseln",
|
||||
"switchToTreeView": "Zur Baumansicht wechseln",
|
||||
"recursiveOn": "Unterordner durchsuchen",
|
||||
"recursiveOff": "Nur aktuellen Ordner durchsuchen",
|
||||
"recursiveUnavailable": "Rekursive Suche ist nur in der Baumansicht verfügbar",
|
||||
"collapseAllDisabled": "Im Listenmodus nicht verfügbar"
|
||||
},
|
||||
"statistics": {
|
||||
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "Embedding Models"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "Model Root",
|
||||
"modelRoot": "Root",
|
||||
"collapseAll": "Collapse All Folders",
|
||||
"pinSidebar": "Pin Sidebar",
|
||||
"unpinSidebar": "Unpin Sidebar",
|
||||
"switchToListView": "Switch to List View",
|
||||
"switchToTreeView": "Switch to Tree View",
|
||||
"recursiveOn": "Search subfolders",
|
||||
"recursiveOff": "Search current folder only",
|
||||
"recursiveUnavailable": "Recursive search is available in tree view only",
|
||||
"collapseAllDisabled": "Not available in list view"
|
||||
},
|
||||
"statistics": {
|
||||
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "Modelos embedding"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "Raíz del modelo",
|
||||
"modelRoot": "Raíz",
|
||||
"collapseAll": "Colapsar todas las carpetas",
|
||||
"pinSidebar": "Fijar barra lateral",
|
||||
"unpinSidebar": "Desfijar barra lateral",
|
||||
"switchToListView": "Cambiar a vista de lista",
|
||||
"switchToTreeView": "Cambiar a vista de árbol",
|
||||
"recursiveOn": "Buscar en subcarpetas",
|
||||
"recursiveOff": "Buscar solo en la carpeta actual",
|
||||
"recursiveUnavailable": "La búsqueda recursiva solo está disponible en la vista en árbol",
|
||||
"collapseAllDisabled": "No disponible en vista de lista"
|
||||
},
|
||||
"statistics": {
|
||||
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "Modèles Embedding"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "Racine du modèle",
|
||||
"modelRoot": "Racine",
|
||||
"collapseAll": "Réduire tous les dossiers",
|
||||
"pinSidebar": "Épingler la barre latérale",
|
||||
"unpinSidebar": "Désépingler la barre latérale",
|
||||
"switchToListView": "Passer en vue liste",
|
||||
"switchToTreeView": "Passer en vue arborescence",
|
||||
"recursiveOn": "Rechercher dans les sous-dossiers",
|
||||
"recursiveOff": "Rechercher uniquement dans le dossier actuel",
|
||||
"recursiveUnavailable": "La recherche récursive n'est disponible qu'en vue arborescente",
|
||||
"collapseAllDisabled": "Non disponible en vue liste"
|
||||
},
|
||||
"statistics": {
|
||||
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "מודלי Embedding"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "שורש המודלים",
|
||||
"modelRoot": "שורש",
|
||||
"collapseAll": "כווץ את כל התיקיות",
|
||||
"pinSidebar": "נעל סרגל צד",
|
||||
"unpinSidebar": "שחרר סרגל צד",
|
||||
"switchToListView": "עבור לתצוגת רשימה",
|
||||
"switchToTreeView": "עבור לתצוגת עץ",
|
||||
"switchToTreeView": "תצוגת עץ",
|
||||
"recursiveOn": "חיפוש בתיקיות משנה",
|
||||
"recursiveOff": "חיפוש רק בתיקייה הנוכחית",
|
||||
"recursiveUnavailable": "חיפוש רקורסיבי זמין רק בתצוגת עץ",
|
||||
"collapseAllDisabled": "לא זמין בתצוגת רשימה"
|
||||
},
|
||||
"statistics": {
|
||||
@@ -1264,4 +1267,4 @@
|
||||
"learnMore": "LM Civitai Extension Tutorial"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "Embeddingモデル"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "モデルルート",
|
||||
"modelRoot": "ルート",
|
||||
"collapseAll": "すべてのフォルダを折りたたむ",
|
||||
"pinSidebar": "サイドバーを固定",
|
||||
"unpinSidebar": "サイドバーの固定を解除",
|
||||
"switchToListView": "リストビューに切り替え",
|
||||
"switchToTreeView": "ツリービューに切り替え",
|
||||
"switchToTreeView": "ツリー表示に切り替え",
|
||||
"recursiveOn": "サブフォルダーを検索",
|
||||
"recursiveOff": "現在のフォルダーのみを検索",
|
||||
"recursiveUnavailable": "再帰検索はツリービューでのみ利用できます",
|
||||
"collapseAllDisabled": "リストビューでは利用できません"
|
||||
},
|
||||
"statistics": {
|
||||
@@ -1264,4 +1267,4 @@
|
||||
"learnMore": "LM Civitai Extension Tutorial"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "Embedding 모델"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "모델 루트",
|
||||
"modelRoot": "루트",
|
||||
"collapseAll": "모든 폴더 접기",
|
||||
"pinSidebar": "사이드바 고정",
|
||||
"unpinSidebar": "사이드바 고정 해제",
|
||||
"switchToListView": "목록 보기로 전환",
|
||||
"switchToTreeView": "트리 보기로 전환",
|
||||
"recursiveOn": "하위 폴더 검색",
|
||||
"recursiveOff": "현재 폴더만 검색",
|
||||
"recursiveUnavailable": "재귀 검색은 트리 보기에서만 사용할 수 있습니다",
|
||||
"collapseAllDisabled": "목록 보기에서는 사용할 수 없습니다"
|
||||
},
|
||||
"statistics": {
|
||||
@@ -1264,4 +1267,4 @@
|
||||
"learnMore": "LM Civitai Extension Tutorial"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "Модели Embedding"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "Корень моделей",
|
||||
"modelRoot": "Корень",
|
||||
"collapseAll": "Свернуть все папки",
|
||||
"pinSidebar": "Закрепить боковую панель",
|
||||
"unpinSidebar": "Открепить боковую панель",
|
||||
"switchToListView": "Переключить на вид списка",
|
||||
"switchToTreeView": "Переключить на древовидный вид",
|
||||
"recursiveOn": "Искать во вложенных папках",
|
||||
"recursiveOff": "Искать только в текущей папке",
|
||||
"recursiveUnavailable": "Рекурсивный поиск доступен только в режиме дерева",
|
||||
"collapseAllDisabled": "Недоступно в виде списка"
|
||||
},
|
||||
"statistics": {
|
||||
@@ -1264,4 +1267,4 @@
|
||||
"learnMore": "LM Civitai Extension Tutorial"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -535,12 +535,15 @@
|
||||
"title": "Embedding 模型"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "模型根目录",
|
||||
"modelRoot": "根目录",
|
||||
"collapseAll": "折叠所有文件夹",
|
||||
"pinSidebar": "固定侧边栏",
|
||||
"unpinSidebar": "取消固定侧边栏",
|
||||
"switchToListView": "切换到列表视图",
|
||||
"switchToTreeView": "切换到树状视图",
|
||||
"recursiveOn": "搜索子文件夹",
|
||||
"recursiveOff": "仅搜索当前文件夹",
|
||||
"recursiveUnavailable": "仅在树形视图中可使用递归搜索",
|
||||
"collapseAllDisabled": "列表视图下不可用"
|
||||
},
|
||||
"statistics": {
|
||||
@@ -1270,4 +1273,4 @@
|
||||
"learnMore": "LM Civitai Extension Tutorial"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,12 +529,15 @@
|
||||
"title": "Embedding 模型"
|
||||
},
|
||||
"sidebar": {
|
||||
"modelRoot": "模型根目錄",
|
||||
"modelRoot": "根目錄",
|
||||
"collapseAll": "全部摺疊資料夾",
|
||||
"pinSidebar": "固定側邊欄",
|
||||
"unpinSidebar": "取消固定側邊欄",
|
||||
"switchToListView": "切換至列表檢視",
|
||||
"switchToTreeView": "切換至樹狀檢視",
|
||||
"switchToTreeView": "切換到樹狀檢視",
|
||||
"recursiveOn": "搜尋子資料夾",
|
||||
"recursiveOff": "僅搜尋目前資料夾",
|
||||
"recursiveUnavailable": "遞迴搜尋僅能在樹狀檢視中使用",
|
||||
"collapseAllDisabled": "列表檢視下不可用"
|
||||
},
|
||||
"statistics": {
|
||||
@@ -1264,4 +1267,4 @@
|
||||
"learnMore": "LM Civitai Extension Tutorial"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ export class SidebarManager {
|
||||
this.isInitialized = false;
|
||||
this.displayMode = 'tree'; // 'tree' or 'list'
|
||||
this.foldersList = [];
|
||||
this.recursiveSearchEnabled = true;
|
||||
|
||||
// Bind methods
|
||||
this.handleTreeClick = this.handleTreeClick.bind(this);
|
||||
@@ -36,6 +37,7 @@ export class SidebarManager {
|
||||
this.updateContainerMargin = this.updateContainerMargin.bind(this);
|
||||
this.handleDisplayModeToggle = this.handleDisplayModeToggle.bind(this);
|
||||
this.handleFolderListClick = this.handleFolderListClick.bind(this);
|
||||
this.handleRecursiveToggle = this.handleRecursiveToggle.bind(this);
|
||||
}
|
||||
|
||||
async initialize(pageControls) {
|
||||
@@ -89,6 +91,7 @@ export class SidebarManager {
|
||||
this.isHovering = false;
|
||||
this.apiClient = null;
|
||||
this.isInitialized = false;
|
||||
this.recursiveSearchEnabled = true;
|
||||
|
||||
// Reset container margin
|
||||
const container = document.querySelector('.container');
|
||||
@@ -111,6 +114,7 @@ export class SidebarManager {
|
||||
const sidebar = document.getElementById('folderSidebar');
|
||||
const hoverArea = document.getElementById('sidebarHoverArea');
|
||||
const displayModeToggleBtn = document.getElementById('sidebarDisplayModeToggle');
|
||||
const recursiveToggleBtn = document.getElementById('sidebarRecursiveToggle');
|
||||
|
||||
if (pinToggleBtn) {
|
||||
pinToggleBtn.removeEventListener('click', this.handlePinToggle);
|
||||
@@ -145,6 +149,9 @@ export class SidebarManager {
|
||||
if (displayModeToggleBtn) {
|
||||
displayModeToggleBtn.removeEventListener('click', this.handleDisplayModeToggle);
|
||||
}
|
||||
if (recursiveToggleBtn) {
|
||||
recursiveToggleBtn.removeEventListener('click', this.handleRecursiveToggle);
|
||||
}
|
||||
}
|
||||
|
||||
async init() {
|
||||
@@ -197,7 +204,7 @@ export class SidebarManager {
|
||||
updateSidebarTitle() {
|
||||
const sidebarTitle = document.getElementById('sidebarTitle');
|
||||
if (sidebarTitle) {
|
||||
sidebarTitle.textContent = `${this.apiClient.apiConfig.config.displayName} Root`;
|
||||
sidebarTitle.textContent = translate('sidebar.modelRoot');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +227,12 @@ export class SidebarManager {
|
||||
collapseAllBtn.addEventListener('click', this.handleCollapseAll);
|
||||
}
|
||||
|
||||
// Recursive toggle button
|
||||
const recursiveToggleBtn = document.getElementById('sidebarRecursiveToggle');
|
||||
if (recursiveToggleBtn) {
|
||||
recursiveToggleBtn.addEventListener('click', this.handleRecursiveToggle);
|
||||
}
|
||||
|
||||
// Tree click handler
|
||||
const folderTree = document.getElementById('sidebarFolderTree');
|
||||
if (folderTree) {
|
||||
@@ -645,11 +658,33 @@ export class SidebarManager {
|
||||
this.displayMode = this.displayMode === 'tree' ? 'list' : 'tree';
|
||||
this.updateDisplayModeButton();
|
||||
this.updateCollapseAllButton();
|
||||
this.updateRecursiveToggleButton();
|
||||
this.updateSearchRecursiveOption();
|
||||
this.saveDisplayMode();
|
||||
this.loadFolderTree(); // Reload with new display mode
|
||||
}
|
||||
|
||||
async handleRecursiveToggle(event) {
|
||||
event.stopPropagation();
|
||||
|
||||
if (this.displayMode !== 'tree') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.recursiveSearchEnabled = !this.recursiveSearchEnabled;
|
||||
setStorageItem(`${this.pageType}_recursiveSearch`, this.recursiveSearchEnabled);
|
||||
this.updateSearchRecursiveOption();
|
||||
this.updateRecursiveToggleButton();
|
||||
|
||||
if (this.pageControls && typeof this.pageControls.resetAndReload === 'function') {
|
||||
try {
|
||||
await this.pageControls.resetAndReload(true);
|
||||
} catch (error) {
|
||||
console.error('Failed to reload models after toggling recursive search:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateDisplayModeButton() {
|
||||
const displayModeBtn = document.getElementById('sidebarDisplayModeToggle');
|
||||
if (displayModeBtn) {
|
||||
@@ -679,8 +714,35 @@ export class SidebarManager {
|
||||
}
|
||||
}
|
||||
|
||||
updateRecursiveToggleButton() {
|
||||
const recursiveToggleBtn = document.getElementById('sidebarRecursiveToggle');
|
||||
if (!recursiveToggleBtn) return;
|
||||
|
||||
const icon = recursiveToggleBtn.querySelector('i');
|
||||
const isTreeMode = this.displayMode === 'tree';
|
||||
const isActive = isTreeMode && this.recursiveSearchEnabled;
|
||||
|
||||
recursiveToggleBtn.classList.toggle('active', isActive);
|
||||
recursiveToggleBtn.classList.toggle('disabled', !isTreeMode);
|
||||
recursiveToggleBtn.setAttribute('aria-pressed', isActive ? 'true' : 'false');
|
||||
recursiveToggleBtn.setAttribute('aria-disabled', isTreeMode ? 'false' : 'true');
|
||||
|
||||
if (icon) {
|
||||
icon.className = 'fas fa-code-branch';
|
||||
}
|
||||
|
||||
if (!isTreeMode) {
|
||||
recursiveToggleBtn.title = translate('sidebar.recursiveUnavailable');
|
||||
} else if (this.recursiveSearchEnabled) {
|
||||
recursiveToggleBtn.title = translate('sidebar.recursiveOn');
|
||||
} else {
|
||||
recursiveToggleBtn.title = translate('sidebar.recursiveOff');
|
||||
}
|
||||
}
|
||||
|
||||
updateSearchRecursiveOption() {
|
||||
this.pageControls.pageState.searchOptions.recursive = this.displayMode === 'tree';
|
||||
const isRecursive = this.displayMode === 'tree' && this.recursiveSearchEnabled;
|
||||
this.pageControls.pageState.searchOptions.recursive = isRecursive;
|
||||
}
|
||||
|
||||
updateTreeSelection() {
|
||||
@@ -925,15 +987,18 @@ export class SidebarManager {
|
||||
const isPinned = getStorageItem(`${this.pageType}_sidebarPinned`, true);
|
||||
const expandedPaths = getStorageItem(`${this.pageType}_expandedNodes`, []);
|
||||
const displayMode = getStorageItem(`${this.pageType}_displayMode`, 'tree'); // 'tree' or 'list', default to 'tree'
|
||||
const recursiveSearchEnabled = getStorageItem(`${this.pageType}_recursiveSearch`, true);
|
||||
|
||||
this.isPinned = isPinned;
|
||||
this.expandedNodes = new Set(expandedPaths);
|
||||
this.displayMode = displayMode;
|
||||
this.recursiveSearchEnabled = recursiveSearchEnabled;
|
||||
|
||||
this.updatePinButton();
|
||||
this.updateDisplayModeButton();
|
||||
this.updateCollapseAllButton();
|
||||
this.updateSearchRecursiveOption();
|
||||
this.updateRecursiveToggleButton();
|
||||
}
|
||||
|
||||
restoreSelectedFolder() {
|
||||
@@ -974,4 +1039,4 @@ export class SidebarManager {
|
||||
}
|
||||
|
||||
// Create and export global instance
|
||||
export const sidebarManager = new SidebarManager();
|
||||
export const sidebarManager = new SidebarManager();
|
||||
|
||||
@@ -67,7 +67,7 @@ export const state = {
|
||||
modelname: true,
|
||||
tags: false,
|
||||
creator: false,
|
||||
recursive: true,
|
||||
recursive: getStorageItem(`${MODEL_TYPES.LORA}_recursiveSearch`, true),
|
||||
},
|
||||
filters: {
|
||||
baseModel: [],
|
||||
@@ -116,7 +116,7 @@ export const state = {
|
||||
filename: true,
|
||||
modelname: true,
|
||||
creator: false,
|
||||
recursive: true,
|
||||
recursive: getStorageItem(`${MODEL_TYPES.CHECKPOINT}_recursiveSearch`, true),
|
||||
},
|
||||
filters: {
|
||||
baseModel: [],
|
||||
@@ -144,7 +144,7 @@ export const state = {
|
||||
modelname: true,
|
||||
tags: false,
|
||||
creator: false,
|
||||
recursive: true,
|
||||
recursive: getStorageItem(`${MODEL_TYPES.EMBEDDING}_recursiveSearch`, true),
|
||||
},
|
||||
filters: {
|
||||
baseModel: [],
|
||||
@@ -261,4 +261,4 @@ export function initPageState(pageType) {
|
||||
return getCurrentPageState();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
<button class="sidebar-action-btn" id="sidebarDisplayModeToggle" title="{{ t('sidebar.switchToListView') }}">
|
||||
<i class="fas fa-sitemap"></i>
|
||||
</button>
|
||||
<button class="sidebar-action-btn active" id="sidebarRecursiveToggle" title="{{ t('sidebar.recursiveOn') }}" aria-pressed="true">
|
||||
<i class="fas fa-code-branch"></i>
|
||||
</button>
|
||||
<button class="sidebar-action-btn" id="sidebarCollapseAll" title="{{ t('sidebar.collapseAll') }}">
|
||||
<i class="fas fa-compress-alt"></i>
|
||||
</button>
|
||||
|
||||
Reference in New Issue
Block a user