v31: регионы в таблице/модалке/отчётах + доступ dpp@telecom.kz

This commit is contained in:
Dauren777 2026-06-05 08:30:02 +00:00
parent ef39f491d6
commit 758f4eb72b

View File

@ -105,7 +105,7 @@ td{border-bottom:1px solid var(--gray-200)}tr:hover td{background:var(--cyan-50)
<p class="sub">АО «Казахтелеком» — мониторинг производственной безопасности</p>
<label>Корпоративная почта</label>
<input type="email" id="loginEmail" placeholder="surname@telecom.kz" required>
<p class="hint">curator@telecom.kz (куратор) / admin@telecom.kz / north@telecom.kz (Север) / almaty@telecom.kz (Алматы) — пароль любой</p>
<p class="hint">curator@telecom.kz (куратор, всё) / dpp@telecom.kz (ДПБ, ваш филиал) / пароль любой</p>
<label>Пароль</label>
<input type="password" id="loginPass" placeholder="••••••••" required>
<p class="err" id="loginErr">Неверная почта или пароль</p>
@ -160,6 +160,7 @@ function pct(p){var c=p>=80?"var(--green)":p>=40?"var(--amber)":"var(--red)";ret
var users={
"curator@telecom.kz":{name:"Куратор Плана",branch:0,role:"curator",region:-1},
"dpp@telecom.kz":{name:"Директор ДПБ (Вы)",branch:0,role:"branch",region:0},
"admin@telecom.kz":{name:"Администратор",branch:0,role:"admin",region:-1},
"ahmetov@telecom.kz":{name:"Ахметов К.Т.",branch:6,role:"branch",region:4},
"serikov@telecom.kz":{name:"Сериков А.М.",branch:1,role:"branch",region:3},
@ -295,11 +296,11 @@ function renderDashboard(){
function downloadReport(){
var from=parseInt(document.getElementById("rptFrom").value),to=parseInt(document.getElementById("rptTo").value);
var my=getMy(),csv="№;Мероприятие;Подпункт;Раздел;Дивизион;Статус;Прогресс;Срок;Факт;Отчёт (текст);Файлы\n";
var my=getMy(),csv="№;Регион;Филиал;Мероприятие;Подпункт;Раздел;Статус;Прогресс;Срок;Факт;Отчёт (текст);Файлы\n";
my.forEach(function(e){
function addRow(subLabel,subIdx){var rep="",fls="",d=getMD(e.id,subIdx);
for(var i=from;i<=to;i++){var m=months[i];if(d[m]){if(d[m].report)rep+=M(i)+": "+d[m].report.replace(/"/g,'""')+"; ";if(d[m].files&&d[m].files.length)fls+=M(i)+": "+d[m].files.map(function(f){return f.name}).join(", ")+"; "}}
csv+=e.id+';"'+e.t.replace(/"/g,'""')+'";'+(subLabel||"общее")+';'+sections[e.sec]+';'+branches[e.b]+';'+statusMap[e.s]+';'+e.p+'%;'+e.due+';'+(e.done||"—")+';"'+rep+'";"'+fls+'"\n';}
csv+=e.id+';'+regions[branchRegion[e.b]]+';'+branches[e.b]+';"'+e.t.replace(/"/g,'""')+'";'+(subLabel||"общее")+';'+sections[e.sec]+';'+statusMap[e.s]+';'+e.p+'%;'+e.due+';'+(e.done||"—")+';"'+rep+'";"'+fls+'"\n';}
addRow("",-1);
if(e.sub) e.sub.forEach(function(s,i){ addRow(s.l,i); });
});
@ -314,7 +315,7 @@ function downloadHTML(){
my.forEach(function(e){
var scls={done:"g",warn:"a",late:"r",wait:"w"}[e.s];
h+='<div class="ev"><h3>'+e.id+'. '+esc(e.t)+'</h3>';
h+='<div class="meta"><span>Раздел: <strong>'+sections[e.sec]+'</strong></span><span>Дивизион: <strong>'+branches[e.b]+'</strong></span><span>Срок: <strong>'+e.due+'</strong></span><span>Факт: <strong>'+(e.done||"—")+'</strong></span><span>Прогресс: <strong>'+e.p+'%</strong></span><span class="badge '+scls+'">'+statusMap[e.s]+'</span></div>';
h+='<div class="meta"><span>Регион: <strong>'+regions[branchRegion[e.b]]+'</strong></span><span>Филиал: <strong>'+branches[e.b]+'</strong></span><span>Раздел: <strong>'+sections[e.sec]+'</strong></span><span>Срок: <strong>'+e.due+'</strong></span><span>Факт: <strong>'+(e.done||"—")+'</strong></span><span>Прогресс: <strong>'+e.p+'%</strong></span><span class="badge '+scls+'">'+statusMap[e.s]+'</span></div>';
h+='<div class="meta"><span>Ответственный: <strong>'+esc(e.r)+'</strong></span></div>';
// Main event data
h+=renderMonthBlock(e.id,-1,"Общие материалы",from,to);
@ -352,18 +353,20 @@ function renderMyEvents(){
h+='<div class="filters"><select id="mySF" onchange="renderMyEvents()"><option value="">Все</option><option value="done">Исполнено</option><option value="warn">На контроле</option><option value="late">Просрочено</option><option value="wait">В процессе</option></select></div>';
var sf=document.getElementById("mySF");sf=sf?sf.value:"";
var list=my;if(sf)list=list.filter(function(e){return e.s===sf});
h+='<table><tr><th></th><th>Мероприятие / Подпункты</th><th>Раздел</th><th>Срок</th><th>Прогресс</th><th>Статус</th><th></th></tr>';
h+='<table><tr><th></th><th>Мероприятие / Подпункты</th><th>Регион</th><th>Филиал</th><th>Раздел</th><th>Срок</th><th>Прогресс</th><th>Статус</th><th></th></tr>';
list.forEach(function(e){
var hasSub = e.sub && e.sub.length;
var sc = getSC(e.id);
var subDone = hasSub ? sc.length : 0;
var subTotal = hasSub ? e.sub.length : 0;
h+='<tr><td>'+e.id+'</td>';
h+='<td style="font-size:12px;max-width:340px">';
h+='<td style="font-size:12px;max-width:300px">';
if(hasSub) h+='<span onclick="toggleExpand('+e.id+')" style="cursor:pointer;margin-right:6px">'+(expandedEvents[e.id]?'▼':'▶')+'</span>';
h+='<span title="'+esc(e.t)+'" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:280px;display:inline-block;vertical-align:middle">'+esc(e.t)+'</span>';
h+='<span title="'+esc(e.t)+'" style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:240px;display:inline-block;vertical-align:middle">'+esc(e.t)+'</span>';
if(hasSub) h+=' <span style="font-size:11px;color:var(--gray-500)">('+subDone+'/'+subTotal+')</span>';
h+='</td>';
h+='<td style="font-size:11px">'+regions[branchRegion[e.b]]+'</td>';
h+='<td style="font-size:11px">'+branches[e.b]+'</td>';
h+='<td><span class="badge blue">'+["I","II","III","IV","V"][e.sec]+'</span></td>';
h+='<td>'+e.due+'</td><td>'+pct(e.p)+'</td><td>'+sb(e.s)+'</td>';
h+='<td><button class="btn btn-sm" onclick="openEdit('+e.id+')">📝</button></td></tr>';
@ -440,7 +443,7 @@ function openEdit(id, mi, si){
var html='<button class="close" onclick="closeEM()">&times;</button>';
html+='<span class="badge blue">Раздел '+["I","II","III","IV","V"][e.sec]+'</span>';
html+='<h3 style="margin:8px 0">'+esc(e.t)+'</h3>';
html+='<div class="meta-row"><div class="fld">Дивизион<strong>'+esc(branches[e.b])+'</strong></div><div class="fld">Ответственный<strong>'+esc(e.r)+'</strong></div><div class="fld">Срок<strong>'+e.due+'</strong></div><div class="fld">Факт<strong>'+e.done+'</strong></div></div>';
html+='<div class="meta-row"><div class="fld">Регион<strong>'+regions[branchRegion[e.b]]+'</strong></div><div class="fld">Дивизион<strong>'+esc(branches[e.b])+'</strong></div><div class="fld">Ответственный<strong>'+esc(e.r)+'</strong></div><div class="fld">Срок<strong>'+e.due+'</strong></div><div class="fld">Факт<strong>'+e.done+'</strong></div></div>';
html+='<div class="field"><label>Статус</label><select id="es"><option value="wait"'+(e.s==="wait"?" selected":"")+'>В процессе</option><option value="warn"'+(e.s==="warn"?" selected":"")+'>На контроле</option><option value="late"'+(e.s==="late"?" selected":"")+'>Просрочено</option><option value="done"'+(e.s==="done"?" selected":"")+'>Исполнено</option></select></div>';
html+='<div class="field"><label>Прогресс (%)</label><input type="range" id="ep" min="0" max="100" value="'+e.p+'" oninput="document.getElementById(\'pv\').textContent=this.value+\'%\'"><span id="pv" style="font-weight:700">'+e.p+'%</span></div>';
html+='<div class="field"><label>Комментарий</label><textarea id="ec" placeholder="Комментарий..."></textarea></div>';