All files / scripts/generate-news-indexes/template/client-script-runtime search.ts

100% Statements 1/1
100% Branches 0/0
100% Functions 0/0
100% Lines 1/1

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99                          7x                                                                                                                                                                          
/**
 * @module generate-news-indexes/template/client-script-runtime/search
 * @description Search dispatcher + URL-param restorer + event wiring.
 * `filterArticles()` is the central pipeline (type/topic/search filter →
 * sort switch → state mutation → URL update → render). `readURLParams()`
 * seeds initial state from the URL on page load. Event wiring sits at the
 * bottom so all referenced functions are already defined.
 *
 * @author Hack23 AB
 * @license Apache-2.0
 */
 
/** Filter dispatcher (incl. sort switch) + URL-param restorer. */
export const SEARCH = `
    function filterArticles() {
      const typeFilter = document.getElementById('filter-type').value;
      const topicFilter = document.getElementById('filter-topic').value;
      const sortFilter = document.getElementById('filter-sort').value;
      const searchQuery = document.getElementById('search-input').value.toLowerCase().trim();
 
      let filtered = [...articles];
 
      if (typeFilter !== 'all') {
        filtered = filtered.filter(article => article.type === typeFilter);
      }
 
      if (topicFilter !== 'all') {
        filtered = filtered.filter(article => article.topics.includes(topicFilter));
      }
 
      if (searchQuery) {
        filtered = filtered.filter(article => article.title.toLowerCase().includes(searchQuery));
      }
 
      switch(sortFilter) {
        case 'date-desc':
          filtered.sort((a, b) => new Date(b.date) - new Date(a.date));
          break;
        case 'date-asc':
          filtered.sort((a, b) => new Date(a.date) - new Date(b.date));
          break;
        case 'title':
          filtered.sort((a, b) => a.title.localeCompare(b.title));
          break;
      }
 
      filteredArticles = filtered;
      if (restoringFromURL) {
        restoringFromURL = false;
      } else {
        visibleCount = PAGE_SIZE;
      }
      updateURL();
      renderPage();
    }
 
    function readURLParams() {
      const params = new URLSearchParams(window.location.search);
 
      function safeSetSelect(id, value) {
        const el = document.getElementById(id);
        if (!el) return;
        const opts = Array.from(el.options);
        if (opts.some(o => o.value === value)) {
          el.value = value;
        }
      }
 
      if (params.has('type')) safeSetSelect('filter-type', params.get('type'));
      if (params.has('topic')) safeSetSelect('filter-topic', params.get('topic'));
      if (params.has('sort')) safeSetSelect('filter-sort', params.get('sort'));
      const searchInput = document.getElementById('search-input');
      if (searchInput && params.has('q')) searchInput.value = params.get('q');
      if (params.has('page')) {
        const page = parseInt(params.get('page'), 10);
        if (!isNaN(page) && page > 1) {
          visibleCount = page * PAGE_SIZE;
          restoringFromURL = true;
        }
      }
    }
 
    document.getElementById('filter-type').addEventListener('change', filterArticles);
    document.getElementById('filter-topic').addEventListener('change', filterArticles);
    document.getElementById('filter-sort').addEventListener('change', filterArticles);
    document.getElementById('load-more-btn').addEventListener('click', loadMore);
    var __clearBtn = document.getElementById('clear-filters-btn');
    if (__clearBtn) __clearBtn.addEventListener('click', clearAllFilters);
 
    let searchTimer;
    document.getElementById('search-input').addEventListener('input', function() {
      clearTimeout(searchTimer);
      searchTimer = setTimeout(filterArticles, 300);
    });
 
    readURLParams();
    filterArticles();
`;