From 1cb45c86bfcf8da84ef0cfd1c42e613f10200905 Mon Sep 17 00:00:00 2001 From: Martin Artnik Date: Wed, 19 Mar 2025 15:55:48 +0100 Subject: [PATCH] Fix and optimize smart annotation rendering [SCI-11698] --- .../repositories/repository_datatable.js | 5 +-- app/javascript/packs/smart_annotations.js | 37 ++++++++++++------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/app/assets/javascripts/repositories/repository_datatable.js b/app/assets/javascripts/repositories/repository_datatable.js index 76a342307..c49ee22d2 100644 --- a/app/assets/javascripts/repositories/repository_datatable.js +++ b/app/assets/javascripts/repositories/repository_datatable.js @@ -499,9 +499,8 @@ var RepositoryDatatable = (function(global) { } function renderSmartAnnotations() { - $(`${TABLE_ID} .text-value`).each(function() { - window.renderElementSmartAnnotations(this); - }); + const scrollElement = $('.repository-table .dataTables_scrollBody')[0]; + window.renderElementSmartAnnotations(scrollElement, '.text-value', scrollElement); } function checkSnapshottingStatus() { diff --git a/app/javascript/packs/smart_annotations.js b/app/javascript/packs/smart_annotations.js index c35541313..1a0697695 100644 --- a/app/javascript/packs/smart_annotations.js +++ b/app/javascript/packs/smart_annotations.js @@ -65,25 +65,34 @@ async function fetchSmartAnnotationData(element) { } } -window.renderElementSmartAnnotations = (element) => { - if (!element.innerHTML.match(SA_REGEX)) return true; +window.renderElementSmartAnnotations = (parentElement, selector, scrollElement = null) => { + // Check if it was not initialized yet and contains SA strings + if (parentElement.classList.contains('sa-initialized' || !parentElement.innerHTML.match(SA_REGEX))) return true; - element.innerHTML = window.renderSmartAnnotations(element.innerHTML); + // Handle rendering smart annotations when innerElement scrolls into viewport + const renderFunction = () => { + const elements = parentElement.querySelectorAll(`${selector}:not(.sa-rendered)`); - // Schedule fetch of data for each annotation element when it scrolls into viewport - element.querySelectorAll('.sa-link, .user-tooltip').forEach((el) => { - if (isInViewport(el)) { - fetchSmartAnnotationData(el); + if (elements.length === 0) { + (scrollElement || window).removeEventListener('scroll', renderFunction); return; } - const fetchFunction = () => { - fetchSmartAnnotationData(el); - window.removeEventListener('scroll', fetchFunction); - }; + elements.forEach((innerElement) => { + if (isInViewport(innerElement)) { + innerElement.innerHTML = window.renderSmartAnnotations(innerElement.innerHTML); + innerElement.classList.add('sa-rendered'); + innerElement.querySelectorAll('.sa-link, .user-tooltip').forEach((el) => { + fetchSmartAnnotationData(el); + }); + } + }); + }; - window.addEventListener('scroll', fetchFunction); - }); + renderFunction(); + (scrollElement || window).addEventListener('scroll', renderFunction); + + parentElement.classList.add('sa-initialized'); return true; }; @@ -107,7 +116,7 @@ $(document).on('click', '.user-tooltip', function () {
-

${escapeHtml(data.info)}

+

${data.info}