fix(recipe): prevent empty grid by removing preserveScroll from refresh triggers

Bug: when scrolling down on recipes page, any operation with
preserveScroll: true would fetch only page 1 data then restore
scroll position to beyond the loaded items, leaving the grid empty.

Fix:
- Remove preserveScroll: true from all 7 must-refresh trigger
  paths (filter, search, sort, import, settings reload, sync,
  rebuild cache, sidebar folder nav)
- Replace full list refresh with updateSingleItem() for repair
  and bulk missing-LoRA download operations
- Update tests to match new scroll-free behavior
This commit is contained in:
Will Miao
2026-06-02 08:15:29 +08:00
parent 1ffa543160
commit b633b22779
10 changed files with 40 additions and 23 deletions

View File

@@ -177,9 +177,7 @@ describe('RecipeSidebarApiClient bulk operations', () => {
);
});
it('preserves scroll position for recipe reloads when requested', async () => {
const scrollSnapshot = { scrollContainer: { scrollTop: 480 }, scrollTop: 480 };
captureScrollPositionMock.mockReturnValue(scrollSnapshot);
it('reloads recipes without preserving scroll', async () => {
global.fetch.mockResolvedValue({
ok: true,
json: async () => ({
@@ -189,18 +187,18 @@ describe('RecipeSidebarApiClient bulk operations', () => {
}),
});
await resetAndReload(false, { preserveScroll: true });
await resetAndReload(false);
expect(captureScrollPositionMock).toHaveBeenCalledTimes(1);
expect(captureScrollPositionMock).not.toHaveBeenCalled();
expect(virtualScrollerMock.refreshWithData).toHaveBeenCalledWith(
[{ id: 'recipe-1' }],
1,
false
);
expect(restoreScrollPositionMock).toHaveBeenCalledWith(scrollSnapshot);
expect(restoreScrollPositionMock).not.toHaveBeenCalled();
});
it('uses scroll-preserving reloads for syncChanges', async () => {
it('uses scroll-free reloads for syncChanges', async () => {
global.fetch.mockResolvedValue({
ok: true,
json: async () => ({
@@ -212,8 +210,8 @@ describe('RecipeSidebarApiClient bulk operations', () => {
await syncChanges();
expect(captureScrollPositionMock).toHaveBeenCalledTimes(1);
expect(restoreScrollPositionMock).toHaveBeenCalledTimes(1);
expect(captureScrollPositionMock).not.toHaveBeenCalled();
expect(restoreScrollPositionMock).not.toHaveBeenCalled();
expect(loadingManagerMock.restoreProgressBar).toHaveBeenCalledTimes(1);
});
});