Compare commits

...

2 Commits

Author SHA1 Message Date
Will Miao
2d7c404ebb fix(recipes): preserve scroll position on filter, search, and folder-driven reloads
Five entry points that trigger recipe page reloads were not passing
preserveScroll: true, causing the page to snap back to top after
filtering, searching, or navigating folders — especially painful with
hundreds of recipes.

- RecipePageControls.resetAndReload() → refreshVirtualScroll() now
  passes { preserveScroll: true } (sidebar folder clicks/drag moves)
- FilterManager applyFilters/clearAllFilters → loadRecipes(true)
  changed to loadRecipes({ preserveScroll: true })
- SearchManager performSearch → loadRecipes(true) changed to
  loadRecipes({ preserveScroll: true })
- SettingsManager reloadContent → loadRecipes() changed to
  loadRecipes({ preserveScroll: true })

The normalizeLoadRecipesOptions boolean path always forces
preserveScroll: false — the object form is required to pass it.
2026-05-04 20:26:13 +08:00
Will Miao
e23d803ecf fix(layout): ensure refresh split-button dropdown renders above breadcrumb nav 2026-05-03 18:14:54 +08:00
5 changed files with 13 additions and 5 deletions

View File

@@ -371,6 +371,14 @@
display: block;
}
/* Elevate the controls stacking context above breadcrumb nav when a dropdown is open,
so the dropdown menu isn't obscured. Only active when dropdown is shown to avoid
the entire controls bar (which can wrap to 2 rows on narrow viewports) covering
the sticky breadcrumb. */
.controls:has(.dropdown-group.active) {
z-index: var(--z-header);
}
.dropdown-item {
display: block;
padding: 6px 15px;

View File

@@ -599,7 +599,7 @@ export class FilterManager {
// Call the appropriate manager's load method based on page type
if (this.currentPage === 'recipes' && window.recipeManager) {
await window.recipeManager.loadRecipes(true);
await window.recipeManager.loadRecipes({ preserveScroll: true });
} else if (this.currentPage === 'loras' || this.currentPage === 'embeddings' || this.currentPage === 'checkpoints') {
// For models page, reset the page and reload
await getModelApiClient().loadMoreWithVirtualScroll(true, false);
@@ -682,7 +682,7 @@ export class FilterManager {
// Reload data using the appropriate method for the current page
if (this.currentPage === 'recipes' && window.recipeManager) {
await window.recipeManager.loadRecipes(true);
await window.recipeManager.loadRecipes({ preserveScroll: true });
} else if (this.currentPage === 'loras' || this.currentPage === 'checkpoints' || this.currentPage === 'embeddings') {
await getModelApiClient().loadMoreWithVirtualScroll(true, true);
}

View File

@@ -301,7 +301,7 @@ export class SearchManager {
// Call the appropriate manager's load method based on page type
if (this.currentPage === 'recipes' && window.recipeManager) {
window.recipeManager.loadRecipes(true); // true to reset pagination
window.recipeManager.loadRecipes({ preserveScroll: true });
} else if (this.currentPage === 'loras' || this.currentPage === 'embeddings' || this.currentPage === 'checkpoints') {
// For models page, reset the page and reload
getModelApiClient().loadMoreWithVirtualScroll(true, false);

View File

@@ -2863,7 +2863,7 @@ export class SettingsManager {
await resetAndReload(false);
} else if (this.currentPage === 'recipes') {
// Reload the recipes without updating folders
await window.recipeManager.loadRecipes();
await window.recipeManager.loadRecipes({ preserveScroll: true });
} else if (this.currentPage === 'checkpoints') {
// Reload the checkpoints without updating folders
await resetAndReload(false);

View File

@@ -19,7 +19,7 @@ class RecipePageControls {
}
async resetAndReload() {
refreshVirtualScroll();
await refreshVirtualScroll({ preserveScroll: true });
}
async refreshModels(fullRebuild = false) {