RUSH 4-sub: filteri Klubovi/Sportaši + manifestacije card view + CRM v2 redesign
RUSH-1 Klubovi: list_klubovi() LEFT JOIN v_klubovi_financiranje (prima_pgz/rss/grad_rijeka, u_godisnjaku, ukupno_potpora). financiran=true sad OR od 3 davatelja (drop legacy klubovi.pgz_sufinanciran s 1312 false-positive). Sort sort=potpora&order=desc. UI: gold ukupno_potpora + tooltip + sortable kolona. Defaults priority view (financirani+godišnjak ON, hns_roster OFF). Test: priority=604, +hns=36, all=1641, financiran=15 sorted ZAMET 80208€. RUSH-2 Sportaši: SELECT widened (slika_url, reprezentativac, kategoriziran, broj_dresa). avatarUrl() helper s 3 forme (apsolutni / lokalni /sport/uploads/avatars / initials fallback) + 32px circular avatar lijevo od imena. Test: priority=3712, no-priority=6086, +hns=1439, 1990-2000=645. RUSH-3 Manifestacije: bugfix razina filter HTTP 500 (ambiguous column nakon LEFT JOIN savezi → m.razina/mjesto/organizator). 3 dropdowna iz meta (26 mjesta / 8 razina / 50 organizatora), view toggle 🃏 Kartice / 📋 Tablica (localStorage), 🔗 link ikona u card+table, source_url → Google fallback. Test: default=3, mjesto=Lošinj=2, razina=Tradicionalna=3, organizator=AK Kvarner=1. RUSH-4 CRM v2: tab strip rewrite (10 taba u spec redu Članarine|Liječnički|Obrasci|E-mail|Accounts|Contacts|Leads|Opps|Activities|Cases, sticky+scrollable+gold underline). Pipeline → Opps tab. Novi e-mail templates tab (5 endpointa, 3 seed templates, +Novi modal). Card layout (.cgrid/.ccard) za Accounts/Contacts/Leads/Opps. Export dropdown 📥 ▾ CSV/XLSX(SheetJS CDN)/PDF na svaki tab. Test: /crm_v2 200, 10/10 tab labela, 10 Export dropdowna + 31 exportTab() handlera. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+144
-44
@@ -1409,6 +1409,7 @@ function renderSaveziShell(){
|
||||
</div>
|
||||
${window.renderPGZToggleBtn ? window.renderPGZToggleBtn('savezi') : ''}
|
||||
<span class="tb-s" id="sav-cnt"></span>
|
||||
<button id="sav-export-btn" class="export-btn" type="button">Export ▾</button>
|
||||
</div>
|
||||
<div id="sav-out"></div>
|
||||
`;
|
||||
@@ -1416,6 +1417,20 @@ function renderSaveziShell(){
|
||||
$('#sav-sport').addEventListener('change', applySaveziFilter);
|
||||
$('#sav-kat').addEventListener('change', applySaveziFilter);
|
||||
$('#sav-pgz').addEventListener('change', applySaveziFilter);
|
||||
// Export ▾ — uses same /v2/savezi/priority-sort URL as the table loader.
|
||||
if (window.attachExportDropdown) {
|
||||
window.attachExportDropdown(
|
||||
document.getElementById('sav-export-btn'),
|
||||
function(){
|
||||
const f = _filters.savezi || {};
|
||||
const useOnly = f.financirani || window._pgz_filter_priority;
|
||||
return '/sport/api' + (useOnly
|
||||
? '/v2/savezi/priority-sort?only=true&limit=500'
|
||||
: '/v2/savezi/priority-sort?only=false&limit=500');
|
||||
},
|
||||
'savezi'
|
||||
);
|
||||
}
|
||||
}
|
||||
function setSaveziView(v){
|
||||
_state.viewSavezi = v;
|
||||
@@ -1535,13 +1550,18 @@ async function loadKlubovi(){
|
||||
const root = $('#pg-klubovi');
|
||||
if(!_cache.klubovi){
|
||||
root.innerHTML = '<div class="loading">Učitavanje klubova…</div>';
|
||||
// BUG-E (2026-05-05): build /api/klubovi URL from explicit _filters.klubovi state.
|
||||
// Defaults: financirani=true + godisnjak=true. When BOTH off → load all.
|
||||
// RUSH-1 (2026-05-05): /api/klubovi URL built from _filters.klubovi state.
|
||||
// Spec (CC_FINAL_RUSH slika 4) — 3 checkboxes:
|
||||
// ☑ Samo financirani (PGŽ + RSS + Grad Rijeka) — single combined
|
||||
// ☑ U godišnjaku
|
||||
// ☐ Ima HNS roster
|
||||
// Backend `financiran=true` is OR of all 3 davateljs (single source of truth
|
||||
// = v_klubovi_financiranje view). Default = priority (fin OR godišnjak).
|
||||
// Sort: ukupno_potpora DESC.
|
||||
const f = _filters.klubovi;
|
||||
const qs = new URLSearchParams();
|
||||
qs.set('limit','2500');
|
||||
qs.set('sort','financiran'); qs.set('order','desc'); // sort by potpore DESC (financiran flag)
|
||||
// financirani + godisnjak combined with kategorija=priority logic:
|
||||
qs.set('sort','potpora'); qs.set('order','desc'); // ukupno_potpora DESC NULLS LAST
|
||||
if(f.financirani && f.godisnjak){
|
||||
qs.set('kategorija','priority'); // OR semantics → priority = financiran OR godišnjak
|
||||
} else if(f.financirani){
|
||||
@@ -1581,11 +1601,10 @@ function renderKluboviShell(){
|
||||
<button id="kl-card" class="${_state.viewKlubovi==='card'?'active':''}" onclick="setKluboviView('card')">Kartice</button>
|
||||
<button id="kl-table" class="${_state.viewKlubovi==='table'?'active':''}" onclick="setKluboviView('table')">Tablica</button>
|
||||
</div>
|
||||
<button class="btn" onclick="exportKlubovi('xlsx')">⬇ XLSX</button>
|
||||
<button class="btn" onclick="exportKlubovi('csv')">⬇ CSV</button>
|
||||
<button class="btn" onclick="enrichBulk('klub', 50, 70)">✨ Obogati (50)</button>
|
||||
${window.renderPGZToggleBtn ? window.renderPGZToggleBtn('klubovi') : ''}
|
||||
<span class="tb-s" id="kl-cnt"></span>
|
||||
<button id="kl-export-btn" class="export-btn" type="button">Export ▾</button>
|
||||
</div>
|
||||
<div id="kl-out"></div>
|
||||
`;
|
||||
@@ -1594,6 +1613,25 @@ function renderKluboviShell(){
|
||||
$('#kl-grad').addEventListener('change', applyKluboviFilter);
|
||||
$('#kl-kat').addEventListener('change', applyKluboviFilter);
|
||||
$('#kl-nk').addEventListener('change', applyKluboviFilter);
|
||||
// Export ▾ — rebuilds the same querystring that loadKlubovi uses.
|
||||
if (window.attachExportDropdown) {
|
||||
window.attachExportDropdown(
|
||||
document.getElementById('kl-export-btn'),
|
||||
function(){
|
||||
const f = _filters.klubovi || {};
|
||||
const qs = new URLSearchParams();
|
||||
qs.set('limit','2500');
|
||||
qs.set('sort','potpora'); qs.set('order','desc');
|
||||
if(f.financirani && f.godisnjak) qs.set('kategorija','priority');
|
||||
else if(f.financirani) qs.set('financiran','true');
|
||||
else if(f.godisnjak) qs.set('godisnjak','true');
|
||||
if(f.hns_roster) qs.set('samo_hns_roster','true');
|
||||
if(window._pgz_filter_priority && !qs.has('kategorija')) qs.set('kategorija','priority');
|
||||
return '/sport/api/klubovi?'+qs.toString();
|
||||
},
|
||||
'klubovi'
|
||||
);
|
||||
}
|
||||
}
|
||||
function setKluboviView(v){
|
||||
_state.viewKlubovi = v;
|
||||
@@ -1634,25 +1672,31 @@ function applyKluboviFilter(){
|
||||
}
|
||||
function renderKluboviGrid(rows){
|
||||
if(!rows.length) return '<div class="empty">Nema rezultata</div>';
|
||||
return '<div class="grid-club">'+rows.map(k => `
|
||||
return '<div class="grid-club">'+rows.map(k => {
|
||||
const finTitle = [k.prima_pgz?'PGŽ':null, k.prima_rss?'RSS':null, k.prima_grad_rijeka?'Grad Rijeka':null].filter(Boolean).join(' + ') || 'financiran';
|
||||
const potpora = (k.ukupno_potpora!=null) ? ' <b style="color:var(--pgz-gold)" title="ukupno potpora">'+fmtEur(k.ukupno_potpora)+'</b>' : '';
|
||||
return `
|
||||
<div class="entity" onclick="openKlub(${k.id})">
|
||||
${k.priority?'<div class="et-tag" style="background:#ffd700;color:#1a1a1a">★ PRIO</div>':(k.nositelj_kvalitete?'<div class="et-tag">N.K.</div>':'')}
|
||||
<div class="et">${(window.pgzBadgePrefix?window.pgzBadgePrefix(k,'klub'):'')}${esc(k.klub||k.sport||'(bez naziva)')}</div>
|
||||
<div class="es">${txt(k.razina,'')} · ${txt(k.grad,'—')}</div>
|
||||
<div class="em">
|
||||
${k.financiran?'<span class="tag gd" title="PGŽ sufinanciran">€</span>':''}
|
||||
${k.financiran?'<span class="tag gd" title="'+esc(finTitle)+'">€</span>':''}
|
||||
${k.godisnjak?'<span class="tag b" title="U godišnjaku">G</span>':''}
|
||||
${potpora}
|
||||
<span><b>${fmtNum(k.registriranih)}</b> reg.</span>
|
||||
<span><b>${fmtNum(k.trenera)}</b> trenera</span>
|
||||
<span><b>${fmtNum(k.reprezentativaca)}</b> repr.</span>
|
||||
</div>
|
||||
</div>`).join('')+'</div>';
|
||||
</div>`;
|
||||
}).join('')+'</div>';
|
||||
}
|
||||
function renderKluboviTable(rows){
|
||||
if(!rows.length) return '<div class="empty">Nema rezultata</div>';
|
||||
return `<div class="card" style="padding:0;overflow-x:auto"><table>
|
||||
<thead><tr><th style="width:34px"><input type="checkbox" id="kl-all" title="Označi sve"></th><th title="PGŽ priority">★</th>${sortHeader('klubovi','klub','Klub','')}${sortHeader('klubovi','sport','Sport','')}${sortHeader('klubovi','razina','Razina','')}${sortHeader('klubovi','grad','Grad','')}${sortHeader('klubovi','registriranih','Reg.','num')}${sortHeader('klubovi','trenera','Trenera','num')}${sortHeader('klubovi','nositelj_kvalitete','Status','')}</tr></thead>
|
||||
<tbody>${rows.map(k => `
|
||||
<thead><tr><th style="width:34px"><input type="checkbox" id="kl-all" title="Označi sve"></th><th title="PGŽ priority">★</th>${sortHeader('klubovi','klub','Klub','')}${sortHeader('klubovi','sport','Sport','')}${sortHeader('klubovi','razina','Razina','')}${sortHeader('klubovi','grad','Grad','')}${sortHeader('klubovi','ukupno_potpora','Potpora','num')}${sortHeader('klubovi','registriranih','Reg.','num')}${sortHeader('klubovi','nositelj_kvalitete','Status','')}</tr></thead>
|
||||
<tbody>${rows.map(k => {
|
||||
const finTitle = [k.prima_pgz?'PGŽ':null, k.prima_rss?'RSS':null, k.prima_grad_rijeka?'Grad Rijeka':null].filter(Boolean).join(' + ') || 'financiran';
|
||||
return `
|
||||
<tr>
|
||||
<td onclick="event.stopPropagation()"><input type="checkbox" class="kl-pick" data-id="${k.id}"></td>
|
||||
<td onclick="openKlub(${k.id})">${k.priority?'<span class="tag gd" title="financiran ili u godišnjaku">★</span>':''}</td>
|
||||
@@ -1660,10 +1704,11 @@ function renderKluboviTable(rows){
|
||||
<td onclick="openKlub(${k.id})">${txt(k.sport)}</td>
|
||||
<td onclick="openKlub(${k.id})">${txt(k.razina)}</td>
|
||||
<td onclick="openKlub(${k.id})">${txt(k.grad)}</td>
|
||||
<td onclick="openKlub(${k.id})" class="num"><b style="color:var(--pgz-gold)">${k.ukupno_potpora!=null?fmtEur(k.ukupno_potpora):'—'}</b></td>
|
||||
<td onclick="openKlub(${k.id})" class="num">${fmtNum(k.registriranih)}</td>
|
||||
<td onclick="openKlub(${k.id})" class="num">${fmtNum(k.trenera)}</td>
|
||||
<td onclick="openKlub(${k.id})">${k.financiran?'<span class="tag gd" title="financiran">€</span>':''}${k.godisnjak?'<span class="tag b" title="godišnjak">G</span>':''}${k.nositelj_kvalitete?'<span class="tag gd">N.K.</span>':''}${k.aktivan?'<span class="tag gr">AKT</span>':'<span class="tag rd">NK</span>'}</td>
|
||||
</tr>`).join('')}</tbody>
|
||||
<td onclick="openKlub(${k.id})">${k.financiran?'<span class="tag gd" title="'+esc(finTitle)+'">€</span>':''}${k.godisnjak?'<span class="tag b" title="godišnjak">G</span>':''}${k.nositelj_kvalitete?'<span class="tag gd">N.K.</span>':''}${k.aktivan?'<span class="tag gr">AKT</span>':'<span class="tag rd">NK</span>'}</td>
|
||||
</tr>`;
|
||||
}).join('')}</tbody>
|
||||
</table></div>`;
|
||||
}
|
||||
|
||||
@@ -2698,77 +2743,131 @@ function openObjekt(id){
|
||||
}
|
||||
|
||||
//=========== MANIFESTACIJE ===========
|
||||
// View mode persisted in localStorage as `_manifViewMode` ('card'|'table')
|
||||
const _manifFilter = {mjesto:'', razina:'', organizator:'', q:''};
|
||||
let _manifMeta = null;
|
||||
let _manifLoadSeq = 0;
|
||||
|
||||
async function loadManifestacije(){
|
||||
const root = $('#pg-manifestacije');
|
||||
if(!_cache.manifestacije){
|
||||
// Restore view mode from localStorage
|
||||
const saved = localStorage.getItem('_manifViewMode');
|
||||
if(saved==='card' || saved==='table') _state.viewManif = saved;
|
||||
if(!_manifMeta){
|
||||
root.innerHTML = '<div class="loading">Učitavanje manifestacija…</div>';
|
||||
const d = await api('/manifestacije-full');
|
||||
if(!d){ root.innerHTML='<div class="empty">Greška pri dohvatu</div>'; return; }
|
||||
_cache.manifestacije = d.rows || (Array.isArray(d) ? d : []);
|
||||
_manifMeta = await api('/v2/manifestacije/meta') || {mjesta:[], razine:[], organizatori:[]};
|
||||
}
|
||||
renderManifShell();
|
||||
applyManifFilter();
|
||||
await reloadManifestacije();
|
||||
}
|
||||
async function reloadManifestacije(){
|
||||
const seq = ++_manifLoadSeq;
|
||||
const out = $('#mn-out');
|
||||
if(out) out.innerHTML = '<div class="loading">Učitavanje…</div>';
|
||||
const cnt = $('#mn-cnt');
|
||||
if(cnt) cnt.textContent = '…';
|
||||
const params = new URLSearchParams();
|
||||
if(_manifFilter.mjesto) params.set('mjesto', _manifFilter.mjesto);
|
||||
if(_manifFilter.razina) params.set('razina', _manifFilter.razina);
|
||||
if(_manifFilter.organizator) params.set('organizator', _manifFilter.organizator);
|
||||
if(_manifFilter.q) params.set('q', _manifFilter.q);
|
||||
params.set('limit', '500');
|
||||
const qs = params.toString();
|
||||
const d = await api('/v2/manifestacije'+(qs?'?'+qs:''));
|
||||
if(seq !== _manifLoadSeq) return; // newer request superseded this one
|
||||
if(!d){
|
||||
if(out) out.innerHTML = '<div class="empty">Greška pri dohvatu</div>';
|
||||
return;
|
||||
}
|
||||
_cache.manifestacije = d.rows || [];
|
||||
renderManifBody();
|
||||
}
|
||||
function renderManifShell(){
|
||||
const root = $('#pg-manifestacije');
|
||||
const razine = Array.from(new Set((_cache.manifestacije||[]).map(m=>m.razina).filter(Boolean))).sort();
|
||||
const meta = _manifMeta || {mjesta:[], razine:[], organizatori:[]};
|
||||
const optList = (arr) => (arr||[]).filter(x=>x!==null && x!==undefined && x!=='').map(v=>'<option value="'+esc(v)+'">'+esc(v)+'</option>').join('');
|
||||
root.innerHTML = `
|
||||
<div class="toolbar">
|
||||
<input type="search" id="mn-q" placeholder="🔍 Pretraži manifestaciju…">
|
||||
<select id="mn-raz"><option value="">Sve razine</option>${razine.map(r=>'<option value="'+esc(r)+'">'+esc(r)+'</option>').join('')}</select>
|
||||
<input type="search" id="mn-q" placeholder="🔍 Pretraži manifestaciju…" value="${esc(_manifFilter.q)}">
|
||||
<select id="mn-mjesto" title="Mjesto"><option value="">Sva mjesta</option>${optList(meta.mjesta)}</select>
|
||||
<select id="mn-raz" title="Razina"><option value="">Sve razine</option>${optList(meta.razine)}</select>
|
||||
<select id="mn-org" title="Organizator"><option value="">Svi organizatori</option>${optList(meta.organizatori)}</select>
|
||||
<button id="mn-reset" class="btn" type="button" title="Poništi filtere">↺ Reset</button>
|
||||
<div class="toggle">
|
||||
<button id="mn-card" class="${_state.viewManif==='card'?'active':''}" onclick="setManifView('card')">Kartice</button>
|
||||
<button id="mn-table" class="${_state.viewManif==='table'?'active':''}" onclick="setManifView('table')">Tablica</button>
|
||||
<button id="mn-card" class="${_state.viewManif==='card'?'active':''}" onclick="setManifView('card')" title="Kartice">🃏 Kartice</button>
|
||||
<button id="mn-table" class="${_state.viewManif==='table'?'active':''}" onclick="setManifView('table')" title="Tablica">📋 Tablica</button>
|
||||
</div>
|
||||
<span class="tb-s" id="mn-cnt"></span>
|
||||
</div>
|
||||
<div id="mn-out"></div>
|
||||
`;
|
||||
$('#mn-q').addEventListener('input', debounce(applyManifFilter, 200));
|
||||
$('#mn-raz').addEventListener('change', applyManifFilter);
|
||||
// Restore selections after re-render
|
||||
if($('#mn-mjesto')) $('#mn-mjesto').value = _manifFilter.mjesto;
|
||||
if($('#mn-raz')) $('#mn-raz').value = _manifFilter.razina;
|
||||
if($('#mn-org')) $('#mn-org').value = _manifFilter.organizator;
|
||||
$('#mn-q').addEventListener('input', debounce(()=>{ _manifFilter.q = $('#mn-q').value.trim(); reloadManifestacije(); }, 250));
|
||||
$('#mn-mjesto').addEventListener('change', ()=>{ _manifFilter.mjesto = $('#mn-mjesto').value; reloadManifestacije(); });
|
||||
$('#mn-raz').addEventListener('change', ()=>{ _manifFilter.razina = $('#mn-raz').value; reloadManifestacije(); });
|
||||
$('#mn-org').addEventListener('change', ()=>{ _manifFilter.organizator = $('#mn-org').value; reloadManifestacije(); });
|
||||
$('#mn-reset').addEventListener('click', ()=>{
|
||||
_manifFilter.mjesto=''; _manifFilter.razina=''; _manifFilter.organizator=''; _manifFilter.q='';
|
||||
$('#mn-q').value=''; $('#mn-mjesto').value=''; $('#mn-raz').value=''; $('#mn-org').value='';
|
||||
reloadManifestacije();
|
||||
});
|
||||
}
|
||||
function setManifView(v){
|
||||
_state.viewManif = v;
|
||||
$('#mn-card').classList.toggle('active', v==='card');
|
||||
$('#mn-table').classList.toggle('active', v==='table');
|
||||
applyManifFilter();
|
||||
try{ localStorage.setItem('_manifViewMode', v); }catch(_){}
|
||||
if($('#mn-card')) $('#mn-card').classList.toggle('active', v==='card');
|
||||
if($('#mn-table')) $('#mn-table').classList.toggle('active', v==='table');
|
||||
renderManifBody();
|
||||
}
|
||||
function applyManifFilter(){
|
||||
const q = (($('#mn-q')?$('#mn-q').value:'') || '').toLowerCase().trim();
|
||||
const raz = $('#mn-raz') ? $('#mn-raz').value : '';
|
||||
function renderManifBody(){
|
||||
let rows = _cache.manifestacije || [];
|
||||
if(q) rows = rows.filter(m => (m.naziv||'').toLowerCase().includes(q) || (m.organizator||'').toLowerCase().includes(q) || (m.mjesto||'').toLowerCase().includes(q));
|
||||
if(raz) rows = rows.filter(m => m.razina===raz);
|
||||
if(_sort.manifestacije) rows = sortRows(rows, _sort.manifestacije.key, _sort.manifestacije.dir);
|
||||
$('#mn-cnt').textContent = rows.length+' manifestacija';
|
||||
$('#mn-out').innerHTML = _state.viewManif==='card' ? renderManifGrid(rows) : renderManifTable(rows);
|
||||
}
|
||||
// Backwards-compat: existing handlers (e.g. sortHeader) call applyManifFilter()
|
||||
function applyManifFilter(){ renderManifBody(); }
|
||||
function manifLinkFor(m){
|
||||
if(m && m.source_url) return m.source_url;
|
||||
const gq = encodeURIComponent(((m&&m.naziv)||'')+' '+((m&&m.mjesto)||'')+' sport');
|
||||
return 'https://www.google.com/search?q='+gq;
|
||||
}
|
||||
function renderManifGrid(rows){
|
||||
if(!rows.length) return '<div class="empty">Nema rezultata</div>';
|
||||
return '<div class="grid">'+rows.map(m => `
|
||||
if(!rows.length) return '<div class="empty">Nema manifestacija za zadane filtere</div>';
|
||||
return '<div class="grid">'+rows.map(m => {
|
||||
const url = manifLinkFor(m);
|
||||
const linkIcon = '<a class="et-link" href="'+esc(url)+'" target="_blank" rel="noopener" onclick="event.stopPropagation()" title="'+(m.source_url?'Otvori izvor':'Pretraži online')+'">🔗</a>';
|
||||
return `
|
||||
<div class="entity" onclick="openManif(${m.id})">
|
||||
${m.razina?'<div class="et-tag">'+esc(m.razina)+'</div>':''}
|
||||
<div class="et">${esc(m.naziv)}</div>
|
||||
<div class="es">${txt(m.mjesto,'—')}${m.spol_kategorija?' · '+esc(m.spol_kategorija):''}</div>
|
||||
<div class="et">${esc(m.naziv)} ${linkIcon}</div>
|
||||
<div class="es">${txt(m.mjesto,'—')}${m.spol_kategorija?' · '+esc(m.spol_kategorija):''}${m.godina_od?' · od '+esc(m.godina_od):''}</div>
|
||||
<div class="em">
|
||||
${m.broj_ucesnika?'<span><b>'+esc(m.broj_ucesnika)+'</b> sudionika</span>':''}
|
||||
${m.organizator?'<span>'+esc((m.organizator||'').slice(0,40))+'</span>':''}
|
||||
</div>
|
||||
</div>`).join('')+'</div>';
|
||||
</div>`;
|
||||
}).join('')+'</div>';
|
||||
}
|
||||
function renderManifTable(rows){
|
||||
if(!rows.length) return '<div class="empty">Nema rezultata</div>';
|
||||
if(!rows.length) return '<div class="empty">Nema manifestacija za zadane filtere</div>';
|
||||
return `<div class="card" style="padding:0;overflow-x:auto"><table>
|
||||
<thead><tr>${sortHeader('manifestacije','naziv','Naziv','')}${sortHeader('manifestacije','mjesto','Mjesto','')}${sortHeader('manifestacije','razina','Razina','')}${sortHeader('manifestacije','organizator','Organizator','')}${sortHeader('manifestacije','broj_ucesnika','Sudionici','')}<th>Link</th></tr></thead>
|
||||
<tbody>${rows.map(m => `
|
||||
<tbody>${rows.map(m => {
|
||||
const url = manifLinkFor(m);
|
||||
return `
|
||||
<tr onclick="openManif(${m.id})">
|
||||
<td><b>${esc(m.naziv)}</b></td>
|
||||
<td>${txt(m.mjesto)}</td>
|
||||
<td>${m.razina?'<span class="tag b">'+esc(m.razina)+'</span>':'—'}</td>
|
||||
<td>${txt(m.organizator)}</td>
|
||||
<td>${txt(m.broj_ucesnika)}</td>
|
||||
<td>${m.source_url?'<a href="'+esc(m.source_url)+'" target="_blank">↗</a>':'—'}</td>
|
||||
</tr>`).join('')}</tbody>
|
||||
<td><a href="${esc(url)}" target="_blank" rel="noopener" onclick="event.stopPropagation()" title="${m.source_url?'Otvori izvor':'Pretraži online'}">🔗</a></td>
|
||||
</tr>`;
|
||||
}).join('')}</tbody>
|
||||
</table></div>`;
|
||||
}
|
||||
function openManif(id){
|
||||
@@ -3815,5 +3914,6 @@ window.closePanel = function(){
|
||||
if(ov){ ov.classList.remove('open'); ov.style.removeProperty('display'); }
|
||||
};
|
||||
</script>
|
||||
<script src="/static/js/export_dropdown.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user