diff --git a/static/js/app/filesView.js b/static/js/app/filesView.js index 5f7893be..62769d41 100644 --- a/static/js/app/filesView.js +++ b/static/js/app/filesView.js @@ -496,6 +496,21 @@ async function loadFiles(options = { insertHistory: true }) { } } +/** + * Replace the list contents with a whole result set in one batched render + * (single DocumentFragment pass — no per-item DOM scans, smooth-scrolls or + * highlight pulses). Used by search to display results; optimistic + * single-item inserts should keep using `addItem`. + * + * @param {Array} items + */ +function renderItems(items) { + const component = _ensureComponent(); + if (!component) return; + document.getElementById('files-container-error')?.classList.add('hidden'); + component.render(items); +} + /** * Re-evaluate the shared badge for every item currently rendered in the Files list. * Call this after the outgoing grants cache has been refreshed. @@ -504,4 +519,4 @@ function refreshSharedBadges() { _component?.refreshSharedBadges(); } -export { addItem, filesView, loadFiles, refreshSharedBadges }; +export { addItem, filesView, loadFiles, refreshSharedBadges, renderItems }; diff --git a/static/js/features/files/search.js b/static/js/features/files/search.js index 8db9fa5a..73d5bbac 100644 --- a/static/js/features/files/search.js +++ b/static/js/features/files/search.js @@ -7,7 +7,7 @@ * displays the enriched results returned by the server. */ -import { addItem as filesViewAddItem, loadFiles } from '../../app/filesView.js'; +import { loadFiles, renderItems } from '../../app/filesView.js'; import { app } from '../../app/state.js'; import { ui } from '../../app/ui.js'; import { getAuthHeaders } from './fileOperations.js'; @@ -198,15 +198,10 @@ const search = { return; } - // Render folders (server-provided enriched data) - results.folders.forEach((folder) => { - filesViewAddItem(folder); - }); - - // Render files (server-provided enriched data) - results.files.forEach((file) => { - filesViewAddItem(file); - }); + // Render the whole result set (server-provided enriched data) in one + // batched pass — per-item inserts would trigger a DOM scan, a smooth + // scroll and a highlight pulse for each of up to 100 rows. + renderItems([...results.folders, ...results.files]); }, /**