1(function () { 2 const filters = document.getElementById('WorkFilters'); 3 const grid = document.getElementById('WorkGridContent'); 4 5 6 7 8 if (!filters || !grid) return; 9 10 const ajaxURL = (window.WorkAjax && WorkAjax.ajax_url) || ''; 11 if (!ajaxURL) { console.error('Missing WorkAjax.ajax_url'); return; } 12 13 function setActive(slug) { 14 filters.querySelectorAll('.FilterButtons__button').forEach(b => 15 b.classList.toggle('FilterButtons__active', (b.dataset.service || '') === (slug || '')) 16 ); 17 } 18 19 async function fetchGrid(slug) { 20 const body = new URLSearchParams({ 21 action: 'fetch_work_items', 22 service: slug || '', 23 _ajax_nonce: (window.WorkAjax && WorkAjax.nonce) || '' 24 }); 25 const res = await fetch(ajaxURL, { 26 method: 'POST', 27 headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 28 credentials: 'same-origin', 29 body 30 }); 31 if (!res.ok) { 32 console.error('AJAX HTTP', res.status, await res.text()); 33 return; 34 } 35 const data = await res.json(); 36 grid.innerHTML = (data && data.success) ? data.data.html : '<p class="WorkGrid__empty">Error.</p>'; 37 } 38 39 function updateURL(slug, replace=false) { 40 const url = new URL(location.href); 41 slug ? url.searchParams.set('service', slug) : url.searchParams.delete('service'); 42 const state = { service: slug || '' }; 43 replace ? history.replaceState(state, '', url) : history.pushState(state, '', url); 44 } 45 46 // 1) First load: ONLY fetch if ?service= is present (otherwise keep SSR "All") 47 const initial = new URLSearchParams(location.search).get('service') || ''; 48 setActive(initial); 49 if (initial) fetchGrid(initial).then(() => updateURL(initial, true)); 50 51 // 2) Clicks: update URL + fetch 52 filters.addEventListener('click', (e) => { 53 const a = e.target.closest('.FilterButtons__button, .FilterButtons__clearFilters'); 54 if (!a) return; 55 if (e.metaKey || e.ctrlKey || e.shiftKey || e.button === 1) return; // allow new tab 56 e.preventDefault(); 57 const slug = a.getAttribute('data-service') || ''; 58 setActive(slug); 59 updateURL(slug); 60 fetchGrid(slug); 61 }); 62 63 // 3) Back/forward 64 window.addEventListener('popstate', () => { 65 const slug = (history.state && history.state.service) || 66 (new URLSearchParams(location.search).get('service') || ''); 67 setActive(slug); 68 if (slug) fetchGrid(slug); 69 else location.reload(); // go back to cacheable SSR "All" 70 }); 71})(); 72 73 74
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.