From 5f1bd894b9dddeb3f5548ab869cf4546fdc5e7f1 Mon Sep 17 00:00:00 2001 From: Will Miao Date: Sat, 11 Apr 2026 16:20:37 +0800 Subject: [PATCH] fix(settings): prevent library modal focus jump --- static/js/managers/SettingsManager.js | 6 +-- .../managers/settingsManager.library.test.js | 46 +++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/static/js/managers/SettingsManager.js b/static/js/managers/SettingsManager.js index df441970..dda95daf 100644 --- a/static/js/managers/SettingsManager.js +++ b/static/js/managers/SettingsManager.js @@ -1443,12 +1443,12 @@ export class SettingsManager { // Add empty row for new path if no paths exist if (paths.length === 0) { - this.addExtraFolderPathRow(modelType, ''); + this.addExtraFolderPathRow(modelType, '', false); } }); } - addExtraFolderPathRow(modelType, path = '') { + addExtraFolderPathRow(modelType, path = '', shouldFocus = true) { const container = document.getElementById(`extraFolderPaths-${modelType}`); if (!container) return; @@ -1472,7 +1472,7 @@ export class SettingsManager { container.appendChild(row); // Focus the input if it's empty (new row) - if (!path) { + if (!path && shouldFocus) { const input = row.querySelector('.extra-folder-path-input'); if (input) { setTimeout(() => input.focus(), 0); diff --git a/tests/frontend/managers/settingsManager.library.test.js b/tests/frontend/managers/settingsManager.library.test.js index e63a8f67..18cd2c24 100644 --- a/tests/frontend/managers/settingsManager.library.test.js +++ b/tests/frontend/managers/settingsManager.library.test.js @@ -96,6 +96,7 @@ beforeEach(() => { }); afterEach(() => { + vi.useRealTimers(); delete global.fetch; delete document.hidden; Object.defineProperty(window, 'location', { @@ -231,6 +232,51 @@ describe('SettingsManager library controls', () => { expect(input.value).toBe('/custom/recipes'); }); + it('does not autofocus empty extra folder path rows during initial settings load', async () => { + vi.useFakeTimers(); + + const manager = createManager(); + document.body.innerHTML = ` +
+
+
+
+ `; + + vi.spyOn(manager, 'loadMetadataArchiveSettings').mockResolvedValue(); + vi.spyOn(manager, 'loadBackupSettings').mockResolvedValue(); + vi.spyOn(manager, 'loadLibraries').mockResolvedValue(); + vi.spyOn(manager, 'loadLoraRoots').mockResolvedValue(); + vi.spyOn(manager, 'loadCheckpointRoots').mockResolvedValue(); + vi.spyOn(manager, 'loadUnetRoots').mockResolvedValue(); + vi.spyOn(manager, 'loadEmbeddingRoots').mockResolvedValue(); + + const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus').mockImplementation(() => {}); + + state.global.settings = { + extra_folder_paths: {}, + }; + + await manager.loadSettingsToUI(); + await vi.runAllTimersAsync(); + + expect(focusSpy).not.toHaveBeenCalled(); + }); + + it('still focuses an extra folder path row when it is added explicitly', async () => { + vi.useFakeTimers(); + + const manager = createManager(); + document.body.innerHTML = '
'; + + const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus').mockImplementation(() => {}); + + manager.addExtraFolderPathRow('embeddings', ''); + await vi.runAllTimersAsync(); + + expect(focusSpy).toHaveBeenCalledTimes(1); + }); + it('shows loading while saving recipes_path', async () => { const manager = createManager(); const input = document.createElement('input');