feat: add update availability filter to model list

Add a new filter option to show only models with available updates across all supported languages. This includes:

- Adding "updates" filter translations in all locale files (de, en, es, fr, he, ja, ko)
- Extending BaseModelApiClient to handle update_available_only query parameter
- Implementing update filter button in PageControls component with event listeners
- Adding corresponding CSS styles for active filter state

The feature allows users to quickly identify and focus on models that have updates available, improving the update management workflow.
This commit is contained in:
Will Miao
2025-10-29 07:32:53 +08:00
parent 7770976513
commit b10bcf7e78
20 changed files with 300 additions and 98 deletions

View File

@@ -30,6 +30,9 @@ export class PageControls {
// Initialize event listeners
this.initEventListeners();
// Initialize update availability filter button state
this.initUpdateAvailableFilter();
// Initialize favorites filter button state
this.initFavoritesFilter();
@@ -189,12 +192,17 @@ export class PageControls {
if (bulkButton) {
bulkButton.addEventListener('click', () => this.toggleBulkMode());
}
// Favorites filter button handler
const favoriteFilterBtn = document.getElementById('favoriteFilterBtn');
if (favoriteFilterBtn) {
favoriteFilterBtn.addEventListener('click', () => this.toggleFavoritesOnly());
}
const updateFilterBtn = document.getElementById('updateFilterBtn');
if (updateFilterBtn) {
updateFilterBtn.addEventListener('click', () => this.toggleUpdateAvailableOnly());
}
}
/**
@@ -378,17 +386,33 @@ export class PageControls {
// Get current state from session storage with page-specific key
const storageKey = `show_favorites_only_${this.pageType}`;
const showFavoritesOnly = getSessionItem(storageKey, false);
// Update button state
if (showFavoritesOnly) {
favoriteFilterBtn.classList.add('active');
}
// Update app state
this.pageState.showFavoritesOnly = showFavoritesOnly;
}
}
/**
* Initialize update availability filter button state
*/
initUpdateAvailableFilter() {
const storageKey = `show_update_available_only_${this.pageType}`;
const storedValue = getSessionItem(storageKey, false);
const showUpdatesOnly = storedValue === true || storedValue === 'true';
this.pageState.showUpdateAvailableOnly = showUpdatesOnly;
const updateFilterBtn = document.getElementById('updateFilterBtn');
if (updateFilterBtn) {
updateFilterBtn.classList.toggle('active', showUpdatesOnly);
}
}
/**
* Toggle favorites-only filter and reload models
*/
@@ -410,10 +434,29 @@ export class PageControls {
if (favoriteFilterBtn) {
favoriteFilterBtn.classList.toggle('active', newState);
}
// Reload models with new filter
await this.resetAndReload(true);
}
/**
* Toggle update-available-only filter and reload models
*/
async toggleUpdateAvailableOnly() {
const updateFilterBtn = document.getElementById('updateFilterBtn');
const storageKey = `show_update_available_only_${this.pageType}`;
const newState = !this.pageState.showUpdateAvailableOnly;
setSessionItem(storageKey, newState);
this.pageState.showUpdateAvailableOnly = newState;
if (updateFilterBtn) {
updateFilterBtn.classList.toggle('active', newState);
}
await this.resetAndReload(true);
}
/**
* Find duplicate models
@@ -437,4 +480,4 @@ export class PageControls {
this.sidebarManager.cleanup();
}
}
}
}