diff --git a/static/js/checkpoints.js b/static/js/checkpoints.js index fc09463d..3daa4b5c 100644 --- a/static/js/checkpoints.js +++ b/static/js/checkpoints.js @@ -3,6 +3,7 @@ import { toggleApiKeyVisibility } from './managers/SettingsManager.js'; import { initializeInfiniteScroll } from './utils/infiniteScroll.js'; import { confirmDelete, closeDeleteModal } from './utils/modalUtils.js'; import { createPageControls } from './components/controls/index.js'; +import { loadMoreCheckpoints } from './api/checkpointApi.js'; // Initialize the Checkpoints page class CheckpointsPageManager { @@ -19,6 +20,11 @@ class CheckpointsPageManager { window.confirmDelete = confirmDelete; window.closeDeleteModal = closeDeleteModal; window.toggleApiKeyVisibility = toggleApiKeyVisibility; + + // Add loadCheckpoints function to window for FilterManager compatibility + window.checkpointManager = { + loadCheckpoints: (reset) => loadMoreCheckpoints(reset) + }; } async initialize() { diff --git a/static/js/managers/CheckpointSearchManager.js b/static/js/managers/CheckpointSearchManager.js deleted file mode 100644 index 7567bc7b..00000000 --- a/static/js/managers/CheckpointSearchManager.js +++ /dev/null @@ -1,150 +0,0 @@ -/** - * CheckpointSearchManager - Specialized search manager for the Checkpoints page - * Extends the base SearchManager with checkpoint-specific functionality - */ -import { SearchManager } from './SearchManager.js'; -import { state } from '../state/index.js'; -import { showToast } from '../utils/uiHelpers.js'; - -export class CheckpointSearchManager extends SearchManager { - constructor(options = {}) { - super({ - page: 'checkpoints', - ...options - }); - - this.currentSearchTerm = ''; - - // Store this instance in the state - if (state) { - state.searchManager = this; - } - } - - async performSearch() { - const searchTerm = this.searchInput.value.trim().toLowerCase(); - - if (searchTerm === this.currentSearchTerm && !this.isSearching) { - return; // Avoid duplicate searches - } - - this.currentSearchTerm = searchTerm; - - const grid = document.getElementById('checkpointGrid'); - - if (!searchTerm) { - if (state) { - state.currentPage = 1; - } - this.resetAndReloadCheckpoints(); - return; - } - - try { - this.isSearching = true; - if (state && state.loadingManager) { - state.loadingManager.showSimpleLoading('Searching checkpoints...'); - } - - // Store current scroll position - const scrollPosition = window.pageYOffset || document.documentElement.scrollTop; - - if (state) { - state.currentPage = 1; - state.hasMore = true; - } - - const url = new URL('/api/checkpoints', window.location.origin); - url.searchParams.set('page', '1'); - url.searchParams.set('page_size', '20'); - url.searchParams.set('sort_by', state ? state.sortBy : 'name'); - url.searchParams.set('search', searchTerm); - url.searchParams.set('fuzzy', 'true'); - - // Add search options - const searchOptions = this.getActiveSearchOptions(); - url.searchParams.set('search_filename', searchOptions.filename.toString()); - url.searchParams.set('search_modelname', searchOptions.modelname.toString()); - - // Always send folder parameter if there is an active folder - if (state && state.activeFolder) { - url.searchParams.set('folder', state.activeFolder); - // Add recursive parameter when recursive search is enabled - const recursive = this.recursiveSearchToggle ? this.recursiveSearchToggle.checked : false; - url.searchParams.set('recursive', recursive.toString()); - } - - const response = await fetch(url); - - if (!response.ok) { - throw new Error('Search failed'); - } - - const data = await response.json(); - - if (searchTerm === this.currentSearchTerm && grid) { - grid.innerHTML = ''; - - if (data.items.length === 0) { - grid.innerHTML = '
No matching checkpoints found
'; - if (state) { - state.hasMore = false; - } - } else { - this.appendCheckpointCards(data.items); - if (state) { - state.hasMore = state.currentPage < data.total_pages; - state.currentPage++; - } - } - - // Restore scroll position after content is loaded - setTimeout(() => { - window.scrollTo({ - top: scrollPosition, - behavior: 'instant' // Use 'instant' to prevent animation - }); - }, 10); - } - } catch (error) { - console.error('Checkpoint search error:', error); - showToast('Checkpoint search failed', 'error'); - } finally { - this.isSearching = false; - if (state && state.loadingManager) { - state.loadingManager.hide(); - } - } - } - - resetAndReloadCheckpoints() { - // This function would be implemented in the checkpoints page - if (typeof window.loadCheckpoints === 'function') { - window.loadCheckpoints(); - } else { - // Fallback to reloading the page - window.location.reload(); - } - } - - appendCheckpointCards(checkpoints) { - // This function would be implemented in the checkpoints page - const grid = document.getElementById('checkpointGrid'); - if (!grid) return; - - if (typeof window.appendCheckpointCards === 'function') { - window.appendCheckpointCards(checkpoints); - } else { - // Fallback implementation - checkpoints.forEach(checkpoint => { - const card = document.createElement('div'); - card.className = 'checkpoint-card'; - card.innerHTML = ` -

${checkpoint.name}

-

${checkpoint.filename || 'No filename'}

- `; - grid.appendChild(card); - }); - } - } -} \ No newline at end of file diff --git a/static/js/managers/FilterManager.js b/static/js/managers/FilterManager.js index 57cbbf35..1ebdc9e2 100644 --- a/static/js/managers/FilterManager.js +++ b/static/js/managers/FilterManager.js @@ -1,7 +1,8 @@ -import { BASE_MODELS, BASE_MODEL_CLASSES } from '../utils/constants.js'; -import { state, getCurrentPageState } from '../state/index.js'; +import { BASE_MODEL_CLASSES } from '../utils/constants.js'; +import { getCurrentPageState } from '../state/index.js'; import { showToast, updatePanelPositions } from '../utils/uiHelpers.js'; import { loadMoreLoras } from '../api/loraApi.js'; +import { loadMoreCheckpoints } from '../api/checkpointApi.js'; import { removeStorageItem, setStorageItem, getStorageItem } from '../utils/storageHelpers.js'; export class FilterManager { @@ -73,7 +74,7 @@ export class FilterManager { } else if (this.currentPage === 'checkpoints') { tagsEndpoint = '/api/checkpoints/top-tags?limit=20'; } - + const response = await fetch(tagsEndpoint); if (!response.ok) throw new Error('Failed to fetch tags'); @@ -147,7 +148,6 @@ export class FilterManager { apiEndpoint = '/api/recipes/base-models'; } else if (this.currentPage === 'checkpoints') { apiEndpoint = '/api/checkpoints/base-models'; - return; // No API endpoint for other pages } // Fetch base models @@ -283,7 +283,7 @@ export class FilterManager { // For loras page, reset the page and reload await loadMoreLoras(true, true); } else if (this.currentPage === 'checkpoints' && window.checkpointManager) { - await window.checkpointManager.loadCheckpoints(true); + await loadMoreCheckpoints(true); } // Update filter button to show active state @@ -339,8 +339,8 @@ export class FilterManager { await window.recipeManager.loadRecipes(true); } else if (this.currentPage === 'loras') { await loadMoreLoras(true, true); - } else if (this.currentPage === 'checkpoints' && window.checkpointManager) { - await window.checkpointManager.loadCheckpoints(true); + } else if (this.currentPage === 'checkpoints') { + await loadMoreCheckpoints(true); } showToast(`Filters cleared`, 'info');