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:
@@ -199,6 +199,7 @@ table tbody tr:hover{background:var(--bg3)}
|
||||
<label>Status <select id="rac-status"><option value="">— svi —</option><option value="nacrt">Nacrt</option><option value="knjizen">Knjižen</option><option value="placen">Plaćen</option><option value="otkazan">Otkazan</option></select></label>
|
||||
<label>Godina <input type="number" id="rac-godina" value="2026" style="width:90px"></label>
|
||||
<button class="btn" onclick="loadRacuni()">Osvježi</button>
|
||||
<button id="rac-export-btn" class="export-btn" type="button">Export ▾</button>
|
||||
</div>
|
||||
<div class="tbl-wrap">
|
||||
<table id="rac-tbl"><thead><tr><th>#</th><th>Broj</th><th>Datum</th><th>Partner</th><th>OIB</th><th class="num">Neto</th><th class="num">PDV</th><th class="num">Brutto</th><th>Status</th><th>Akcije</th></tr></thead><tbody><tr><td colspan="10" style="color:var(--t2);text-align:center;padding:18px">Klikni "Osvježi" za učitavanje…</td></tr></tbody></table>
|
||||
@@ -253,6 +254,7 @@ table tbody tr:hover{background:var(--bg3)}
|
||||
<label>Status <select id="pn-status"><option value="">— svi —</option><option value="draft">draft</option><option value="podnesen">podnesen</option><option value="odobren">odobren</option><option value="isplacen">isplacen</option><option value="rejected">rejected</option></select></label>
|
||||
<label>Godina <input type="number" id="pn-godina" placeholder="2026" style="width:90px"></label>
|
||||
<button class="btn" onclick="loadExpenseReports()">Osvježi</button>
|
||||
<button id="pn-export-btn" class="export-btn" type="button">Export ▾</button>
|
||||
</div>
|
||||
<div class="tbl-wrap">
|
||||
<table id="pn-tbl"><thead><tr><th>#</th><th>Tip</th><th>Klub</th><th>Odredište</th><th>Svrha</th><th>Od</th><th>Do</th><th class="num">Km</th><th class="num">Trošak</th><th class="num">Dnevnice</th><th>Status</th></tr></thead><tbody><tr><td colspan="11" style="color:var(--t2);text-align:center;padding:18px">Klikni "Osvježi"…</td></tr></tbody></table>
|
||||
@@ -278,6 +280,7 @@ table tbody tr:hover{background:var(--bg3)}
|
||||
<label>Način <select id="py-method"><option value="">— svi —</option><option value="transfer">transfer</option><option value="cash">cash</option><option value="card">card</option></select></label>
|
||||
<label>Godina <input type="number" id="py-godina" placeholder="2026" style="width:90px"></label>
|
||||
<button class="btn" onclick="loadPayments()">Osvježi</button>
|
||||
<button id="py-export-btn" class="export-btn" type="button">Export ▾</button>
|
||||
</div>
|
||||
<div class="tbl-wrap">
|
||||
<table id="py-tbl"><thead><tr><th>#</th><th>Datum</th><th>Klub</th><th class="num">Iznos</th><th>Valuta</th><th>Način</th><th>IBAN OD</th><th>IBAN ZA</th><th>Referenca</th><th>Račun</th><th>Putni nalog</th><th>Match</th></tr></thead><tbody><tr><td colspan="12" style="color:var(--t2);text-align:center;padding:18px">Klikni "Osvježi"…</td></tr></tbody></table>
|
||||
@@ -1228,6 +1231,49 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
loadDnevnik();
|
||||
});
|
||||
|
||||
// ── Universal Export ▾ — wired to representative ERP tabs (racuni,
|
||||
// putni nalozi, payments). Uses live filter values so the exported
|
||||
// rows match what's on screen.
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
if (!window.attachExportDropdown) return;
|
||||
|
||||
const racBtn = document.getElementById('rac-export-btn');
|
||||
if (racBtn) window.attachExportDropdown(racBtn, function(){
|
||||
const tip = (document.getElementById('rac-tip')||{}).value || 'ulazni';
|
||||
const status = (document.getElementById('rac-status')||{}).value || '';
|
||||
const god = (document.getElementById('rac-godina')||{}).value || '';
|
||||
const qp = new URLSearchParams(); qp.set('limit','2000');
|
||||
if (status) qp.set('status', status);
|
||||
if (god) qp.set('godina', god);
|
||||
return '/api/v2/erp/racuni/'+tip+'?'+qp.toString();
|
||||
}, 'racuni');
|
||||
|
||||
const pnBtn = document.getElementById('pn-export-btn');
|
||||
if (pnBtn) window.attachExportDropdown(pnBtn, function(){
|
||||
const t = (document.getElementById('pn-type')||{}).value || '';
|
||||
const s = (document.getElementById('pn-status')||{}).value || '';
|
||||
const g = (document.getElementById('pn-godina')||{}).value || '';
|
||||
const qp = new URLSearchParams(); qp.set('limit','2000');
|
||||
if (t) qp.set('tip', t);
|
||||
if (s) qp.set('status', s);
|
||||
if (g) qp.set('godina', g);
|
||||
return '/api/v2/erp/expense-reports?'+qp.toString();
|
||||
}, 'expense_reports');
|
||||
|
||||
const pyBtn = document.getElementById('py-export-btn');
|
||||
if (pyBtn) window.attachExportDropdown(pyBtn, function(){
|
||||
const s = (document.getElementById('py-status')||{}).value || '';
|
||||
const m = (document.getElementById('py-method')||{}).value || '';
|
||||
const g = (document.getElementById('py-godina')||{}).value || '';
|
||||
const qp = new URLSearchParams(); qp.set('limit','2000');
|
||||
if (s) qp.set('status', s);
|
||||
if (m) qp.set('metoda', m);
|
||||
if (g) qp.set('godina', g);
|
||||
return '/api/v2/erp/payments?'+qp.toString();
|
||||
}, 'payments');
|
||||
});
|
||||
</script>
|
||||
<script src="/static/js/export_dropdown.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user