v47: фильтр по месяцам на вкладке Отчёты
This commit is contained in:
parent
1bda422d7b
commit
4067e3dfcc
46
index.html
46
index.html
@ -209,7 +209,51 @@ function ra(){var all=ev||[],done=all.filter(function(e){return e.s==="done"}).l
|
||||
document.getElementById("pg-an").innerHTML=h}
|
||||
|
||||
// ===== REPORTS =====
|
||||
function rr(){var h='<div class="card"><h3>Сводный отчёт</h3><div class="fr"><select id="rf">'+ms.map(function(m,i){return'<option value="'+i+'">'+M(i)+'</option>'}).join("")+'</select><span>—</span><select id="rt">'+ms.map(function(m,i){return'<option value="'+i+'"'+(i===11?" selected":"")+'>'+M(i)+'</option>'}).join("")+'</select><button class="btn btn-sm" onclick="dCSV()">CSV</button><button class="btn btn-sm" onclick="dHTML()">HTML</button></div>';var b=0;for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf("sf_")===0)b+=localStorage.getItem(k).length*2}h+='<p style="font-size:12px;color:var(--g5);margin-bottom:8px">Хранилище: '+(b>1048576?(b/1048576).toFixed(1)+" МБ":(b/1024).toFixed(0)+" КБ")+'</p>';h+='<button class="btn btn-sm btn-gn" onclick="exp()">💾 Сохранить</button> <button class="btn btn-sm" onclick="document.getElementById(\'if\').click()">📥 Загрузить</button> <input type="file" id="if" accept=".json" style="display:none" onchange="imp(this)"> <button class="btn btn-sm btn-red" onclick="clr()">🗑 Очистить</button></div>';document.getElementById("pg-rp").innerHTML=h}
|
||||
var rptMonth=5;
|
||||
function rr(){var h='<div class="card"><h3>Сводный отчёт</h3><div class="fr"><select id="rf">'+ms.map(function(m,i){return'<option value="'+i+'">'+M(i)+'</option>'}).join("")+'</select><span>—</span><select id="rt">'+ms.map(function(m,i){return'<option value="'+i+'"'+(i===11?" selected":"")+'>'+M(i)+'</option>'}).join("")+'</select><button class="btn btn-sm" onclick="dCSV()">CSV</button><button class="btn btn-sm" onclick="dHTML()">HTML</button></div>';
|
||||
h+='<div class="fr" style="margin-top:12px"><b>Отчётность за месяц:</b><select id="rm2" onchange="rptMonth=parseInt(this.value);rr()">'+ms.map(function(m,i){return'<option value="'+i+'"'+(i===rptMonth?" selected":"")+'>'+M(i)+'</option>'}).join("")+'</select></div>';
|
||||
|
||||
// Show all events with reports for selected month
|
||||
var mk=ms[rptMonth],hasAny=false;
|
||||
(ev||[]).forEach(function(e){
|
||||
var shown=false;
|
||||
// Main event - all regions
|
||||
reg.forEach(function(r,ri){var d=getMD(e.id,ri,-1);if(d[mk]&&(d[mk].report||(d[mk].files&&d[mk].files.length))){shown=true}});
|
||||
// Sub-items
|
||||
if(e.sub)e.sub.forEach(function(s,si){reg.forEach(function(r,ri){var d=getMD(e.id,ri,si);if(d[mk]&&(d[mk].report||(d[mk].files&&d[mk].files.length)))shown=true})});
|
||||
if(!shown)return;hasAny=true;
|
||||
|
||||
h+='<div class="card" style="padding:14px;margin-bottom:8px"><b>'+e.id+'. '+esc(e.t)+'</b> <span style="font-size:11px;color:var(--g5)">'+br[e.b]+'</span>';
|
||||
reg.forEach(function(r,ri){
|
||||
var d=getMD(e.id,ri,-1);
|
||||
if(d[mk]&&(d[mk].report||(d[mk].files&&d[mk].files.length))){
|
||||
h+='<div style="margin:6px 0;padding:8px 12px;background:var(--g1);border-radius:6px"><b style="font-size:12px">'+r+'</b>';
|
||||
if(d[mk].report)h+='<p style="font-size:12px;margin:4px 0">'+esc(d[mk].report)+'</p>';
|
||||
if(d[mk].qty)h+='<span style="font-size:11px;color:var(--c);font-weight:700">Количество: '+d[mk].qty+'</span>';
|
||||
if(d[mk].files&&d[mk].files.length)h+='<div>'+d[mk].files.map(function(f){return'<span class="fl" style="display:inline-flex;margin:2px"><span class="nm" onclick="dlF2('+e.id+','+rptMonth+','+d[mk].files.indexOf(f)+','+ri+',-1)">📄 '+esc(f.name)+'</span><span class="sz">'+(f.size/1024).toFixed(0)+' КБ</span></span>'}).join("")+'</div>';
|
||||
h+='</div>';
|
||||
}
|
||||
// Sub-items
|
||||
if(e.sub)e.sub.forEach(function(s,si){
|
||||
var sd=getMD(e.id,ri,si);
|
||||
if(sd[mk]&&(sd[mk].report||(sd[mk].files&&sd[mk].files.length))){
|
||||
h+='<div style="margin:4px 0 4px 12px;padding:6px 10px;background:var(--g1);border-left:3px solid var(--c);border-radius:4px"><b style="font-size:11px">'+s.l+') '+esc(s.t.slice(0,60))+'...</b>';
|
||||
h+='<span style="font-size:10px;color:var(--g5)"> — '+r+'</span>';
|
||||
if(sd[mk].report)h+='<p style="font-size:11px;margin:2px 0">'+esc(sd[mk].report)+'</p>';
|
||||
if(sd[mk].qty)h+='<span style="font-size:10px;color:var(--c);font-weight:700">Кол-во: '+sd[mk].qty+'</span>';
|
||||
if(sd[mk].files&&sd[mk].files.length)h+='<div>'+sd[mk].files.map(function(f){return'<span class="fl" style="display:inline-flex;margin:2px"><span class="nm" onclick="dlF2('+e.id+','+rptMonth+','+sd[mk].files.indexOf(f)+','+ri+','+si+')">📄 '+esc(f.name)+'</span></span>'}).join("")+'</div>';
|
||||
h+='</div>';
|
||||
}
|
||||
});
|
||||
});
|
||||
h+='</div>';
|
||||
});
|
||||
if(!hasAny)h+='<p style="color:var(--g5);padding:20px">Нет отчётов за '+M(rptMonth)+'</p>';
|
||||
|
||||
var b=0;for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf("sf_")===0)b+=localStorage.getItem(k).length*2}
|
||||
h+='<div style="margin-top:16px;padding-top:12px;border-top:1px solid var(--g2)"><p style="font-size:12px;color:var(--g5);margin-bottom:8px">Хранилище: '+(b>1048576?(b/1048576).toFixed(1)+" МБ":(b/1024).toFixed(0)+" КБ")+'</p>';
|
||||
h+='<button class="btn btn-sm btn-gn" onclick="exp()">💾 Сохранить</button> <button class="btn btn-sm" onclick="document.getElementById(\'if\').click()">📥 Загрузить</button> <input type="file" id="if" accept=".json" style="display:none" onchange="imp(this)"> <button class="btn btn-sm btn-red" onclick="clr()">🗑 Очистить</button></div></div>';
|
||||
document.getElementById("pg-rp").innerHTML=h}
|
||||
function dCSV(){var f=parseInt(document.getElementById("rf").value),t=parseInt(document.getElementById("rt").value);var csv="\uFEFF№;Филиал;Мероприятие;Регион;Статус;Срок\n";(ev||[]).forEach(function(e){reg.forEach(function(r,ri){var d=getMD(e.id,ri,-1),rep="";for(var i=f;i<=t;i++){var m=ms[i];if(d[m]&&d[m].report)rep+=M(i)+": "+d[m].report.replace(/"/g,'""')+"; "}csv+=e.id+';'+br[e.b]+';"'+e.t.replace(/"/g,'""')+'";'+r+';'+st[e.s]+';'+e.due+';"'+rep+'"\n'})});var a=document.createElement("a");a.href=URL.createObjectURL(new Blob([csv]));a.download="otchet.csv";a.click()}
|
||||
function dHTML(){var f=parseInt(document.getElementById("rf").value),t=parseInt(document.getElementById("rt").value);var h='<!DOCTYPE html><html><head><meta charset="utf-8"><title>Отчёт</title><style>body{font:13px/1.4 Arial;max-width:1000px;margin:0 auto;padding:20px}.ev{border:1px solid #ddd;border-radius:8px;padding:14px;margin-bottom:12px}.badge{display:inline-block;padding:2px 6px;border-radius:4px;font-size:10px;font-weight:700}.g{background:#D1FAE5;color:#065F46}.a{background:#FEF3C7;color:#92400E}.r{background:#FEE2E2;color:#991B1B}.m{background:#f5f5f5;padding:6px 10px;border-radius:4px;margin:4px 0}</style></head><body><h2>Сводный отчёт</h2>';ev.forEach(function(e){var cl={done:"g",warn:"a",late:"r",wait:""}[e.s];h+='<div class="ev"><h3>'+e.id+'. '+esc(e.t)+'</h3><p>'+br[e.b]+' | '+sec[e.sec]+' | Срок: '+e.due+' | <span class="badge '+cl+'">'+st[e.s]+'</span></p>';reg.forEach(function(r,ri){var d=getMD(e.id,ri,-1);for(var i=f;i<=t;i++){var m=ms[i];if(d[m]&&d[m].report){h+='<div class="m"><b>'+M(i)+' — '+r+'</b><p>'+esc(d[m].report)+'</p></div>'}}});h+='</div>'});h+='</body></html>';try{var a=document.createElement("a");a.href=URL.createObjectURL(new Blob(["\uFEFF"+h]));a.download="otchet.html";a.click()}catch(e){alert("Слишком большой")}}
|
||||
function exp(){var d={events:ev,date:new Date().toISOString(),files:{},sc:{}};for(var i=0;i<localStorage.length;i++){var k=localStorage.key(i);if(k.indexOf("sf_")===0)d.files[k]=localStorage.getItem(k);if(k.indexOf("ss_")===0)d.sc[k]=localStorage.getItem(k)}var a=document.createElement("a");a.href=URL.createObjectURL(new Blob([JSON.stringify(d)]));a.download="backup.json";a.click()}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user