agper-agen/modules/laporan-view.html
2025-07-06 23:38:24 +07:00

559 lines
24 KiB
HTML

<style>
.signBlock
{
display: none;
}
</style>
<div style="display: grid; width: calc(90vw - 3ch); height: calc(90vh - 3.5em); grid-template-rows: 1fr auto; row-gap: .5em;">
<div>
<div id="vProker" class="viewer" style="height: 100%;" hidden>
<div style="text-align: center; font-size: 1.1em; font-weight: 600;">
Program Kerja Agen Perubahan Tahun <span class="yr"></span>
</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; column-gap: .5ch; margin-bottom: .5em;">
<div style="display: grid; grid-template-columns: auto auto 1fr; column-gap: .5ch;">
<span>Agen</span>
<span>:</span>
<span class="name"></span>
<span>NIP</span>
<span>:</span>
<span class="nip"></span>
<span>Unit Kerja</span>
<span>:</span>
<span class="uk"></span>
</div>
&nbsp;
<div style="display: grid; grid-template-columns: auto auto 1fr; column-gap: .5ch;">
<span>Supervisor</span>
<span>:</span>
<span class="names"></span>
<span>NIP</span>
<span>:</span>
<span class="nips"></span>
&nbsp;
</div>
</div>
<div class="tbwrapper" style="position: absolute; width: 100%; overflow: auto; max-height: calc(100% - 6.25em)">
<table class="bordered">
<colgroup>
<col style="width: 4ch;">
<col style="width: 27ch;">
<col style="min-width: 12ch;">
<col style="width: 8ch;">
<col style="width: 11ch;">
</colgroup>
<thead>
<tr>
<th>No</th>
<th>Kegiatan</th>
<th>Sasaran</th>
<th>Target</th>
<th>Mulai</th>
</tr>
</thead>
<tbody id="pkContent">
</tbody>
<tbody class="signBlock">
<tr>
<td colspan="5">
<div style="display: flex; margin-top: 1em; padding: 2ch; text-align: center; justify-content: space-between;">
<div>
<br>
Agen&nbsp;Perubahan
<br>
<br>
<br>
<span class="name"></span><br>
NIP.&nbsp;<span class="nip"></span>
</div>
<div>
Mengetahui,<br>
<span class="titles"></span>
<br>
<br>
<br>
<span class="names"></span><br>
NIP.&nbsp;<span class="nips"></span>
</div>
<div>
Pekanbaru, <span class="dt"></span>&nbsp;<span class="mth"></span>&nbsp;<span class="yr"></span><br>
<span class="titlee"></span>
<br>
<br>
<br>
<span class="namee"></span><br>
NIP.&nbsp;<span class="nipe"></span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="vRenak" class="viewer" style="height: 100%;" hidden>
<div style="text-align: center; font-size: 1.1em; font-weight: 600;">
Rencana Aksi Agen Perubahan Tahun <span class="yr"></span>
</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; column-gap: .5ch; margin-bottom: .5em;">
<div style="display: grid; grid-template-columns: auto auto 1fr; column-gap: .5ch;">
<span>Agen</span>
<span>:</span>
<span class="name"></span>
<span>NIP</span>
<span>:</span>
<span class="nip"></span>
<span>Unit Kerja</span>
<span>:</span>
<span class="uk"></span>
</div>
&nbsp;
<div style="display: grid; grid-template-columns: auto auto 1fr; column-gap: .5ch;">
<span>Supervisor</span>
<span>:</span>
<span class="names"></span>
<span>NIP</span>
<span>:</span>
<span class="nips"></span>
&nbsp;
</div>
</div>
<div class="tbwrapper" style="position: absolute; width: 100%; overflow: auto; max-height: calc(100% - 6.25em)">
<table class="bordered">
<colgroup>
<col style="width: 4ch;">
<col style="min-width: 20ch;">
<col style="width: 20ch;">
<col style="width: 20ch;">
<col style="width: 8ch;">
<col style="min-width: 20ch;">
<col style="width: 11ch;">
<col style="width: 11ch;">
</colgroup>
<thead>
<tr>
<th>No</th>
<th>Inovasi</th>
<th>Sasaran</th>
<th>Indikator</th>
<th>Target</th>
<th>Aksi</th>
<th>Rencana Mulai</th>
<th>Selesai Pada</th>
</tr>
</thead>
<tbody id="raContent">
</tbody>
<tbody class="signBlock">
<tr>
<td colspan="8">
<div style="display: flex; margin-top: 1em; padding: 2ch; text-align: center; justify-content: space-between;">
<div>
<br>
Agen&nbsp;Perubahan
<br>
<br>
<br>
<span class="name"></span><br>
NIP.&nbsp;<span class="nip"></span>
</div>
<div>
Mengetahui,<br>
<span class="titles"></span>
<br>
<br>
<br>
<span class="names"></span><br>
NIP.&nbsp;<span class="nips"></span>
</div>
<div>
Pekanbaru, <span class="dt"></span>&nbsp;<span class="mth"></span>&nbsp;<span class="yr"></span><br>
<span class="titlee"></span>
<br>
<br>
<br>
<span class="namee"></span><br>
NIP.&nbsp;<span class="nipe"></span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="vEval" class="viewer" style="height: 100%;" hidden>
<div style="text-align: center; font-size: 1.1em; font-weight: 600;">
Evaluasi Program Kerja Agen Perubahan Tahun <span class="yr"></span>
</div>
<div style="display: grid; grid-template-columns: auto 1fr auto; column-gap: .5ch; margin-bottom: .5em;">
<div style="display: grid; grid-template-columns: auto auto 1fr; column-gap: .5ch;">
<span>Agen</span>
<span>:</span>
<span class="name"></span>
<span>NIP</span>
<span>:</span>
<span class="nip"></span>
<span>Unit Kerja</span>
<span>:</span>
<span class="uk"></span>
</div>
&nbsp;
<div style="display: grid; grid-template-columns: auto auto 1fr; column-gap: .5ch;">
<span>Evaluator</span>
<span>:</span>
<span class="namee"></span>
<span>NIP</span>
<span>:</span>
<span class="nipe"></span>
<span>Rating</span>
<span>:</span>
<span><span id="rating"></span></span>
</div>
</div>
<div class="tbwrapper" style="position: absolute; width: 100%; overflow: auto; max-height: calc(100% - 6.25em)">
<table class="bordered">
<colgroup>
<col style="min-width: 18ch;">
<col style="width: 18ch;">
<col style="width: 18ch;">
<col style="width: 8ch;">
<col style="min-width: 18ch;">
<col style="width: 11ch;">
<col style="width: 11ch;">
<col style="width: 18ch;">
<col style="width: 18ch;">
<col style="width: 3ch;">
</colgroup>
<thead>
<tr>
<th>Inovasi</th>
<th>Sasaran</th>
<th>Indikator</th>
<th>Target</th>
<th>Aksi</th>
<th>Rencana Mulai</th>
<th>Selesai Pada</th>
<th>Kendala dan Solusi</th>
<th>Catatan Evaluasi</th>
<th></th>
</tr>
</thead>
<tbody id="evContent">
</tbody>
<tbody class="signBlock">
<tr>
<td colspan="10">
<div style="display: flex; margin-top: 1em; padding: 2ch; text-align: center; justify-content: space-between;">
<div>
<br>
Agen&nbsp;Perubahan
<br>
<br>
<br>
<span class="name"></span><br>
NIP.&nbsp;<span class="nip"></span>
</div>
<div>
Mengetahui,<br>
<span class="titles"></span>
<br>
<br>
<br>
<span class="names"></span><br>
NIP.&nbsp;<span class="nips"></span>
</div>
<div>
Pekanbaru, <span class="dt"></span>&nbsp;<span class="mth"></span>&nbsp;<span class="yr"></span><br>
<span class="titlee"></span>
<br>
<br>
<br>
<span class="namee"></span><br>
NIP.&nbsp;<span class="nipe"></span>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div style="display: grid; grid-template-columns: auto auto 1fr auto; gap: .25ch;">
<div>
<button id="proker">Program Kerja</button>
</div>
<div>
<button id="renak">Rencana Aksi</button>
</div>
<div>
<button id="eval">Evaluasi</button>
</div>
<button id="print"><m-inline>print</m-inline></button>
</div>
</div>
<script type="module">
const thisDialog = moly.lastDialog();
const data = thisDialog.data;
const loadid = moly.loadScreen.show("Menyiapkan Laporan...","dots","#"+µ('[id^="db"]')[0].id);
const kegiatanName = [
"Sebagai Katalis",
"Sebagai Penggerak Perubahan",
"Sebagai Pemberi Solusi",
"Sebagai Mediator",
"Sebagai Penghubung"
]
const statusName = [
"Draft",
"Ditolak",
"Diajukan",
"Berjalan",
"Lebih Awal",
"Tepat Waktu",
"Terlambat",
"Tidak Terlaksana"
]
function µ(selector)
{
if (selector) return $(thisDialog.box).find(selector);
return $(thisDialog.box);
}
let units = await getJson("/api/getunits");
if(units.status != 200)
{
moly.loadScreen.update(loadid,"Gagal mengumpulkan data. Harap ulangi beberapa saat lagi.");
}
let users = await getJson("/api/getusers");
if(users.status != 200)
{
moly.loadScreen.update(loadid,"Gagal mengumpulkan data. Harap ulangi beberapa saat lagi.");
}
const ourpeople = new Set(agents.map(a=>a.agentID));
users = users.data.filter(u=>ourpeople.has(u.agentID));
const spv = agents.find(a=>a.agentID == users.find(u=>u.level == 2).agentID);
const evr = agents.find(a=>a.agentID == users.find(u=>u.level == 1).agentID);
console.log(spv, evr)
units = units.data;
data.unitKerja = units.find(u=>u.deplID == data.deplID)?.unitKerja;
let printTitle="Cetak Laporan";
µ('#proker').click(()=>{
µ('.viewer').prop("hidden",true);
µ('.viewer').removeClass("print");
µ('#vProker').prop("hidden",false);
µ('#vProker').addClass("print");
µ('.positive').removeClass("positive");
µ('#proker').addClass("positive");
printTitle = `Program Kerja Agen Perubahan ${data.name} Tahun ${data.prokers[0].year}`;
});
µ('#renak').click(()=>{
µ('.viewer').prop("hidden",true);
µ('.viewer').removeClass("print");
µ('#vRenak').prop("hidden",false);
µ('#vRenak').addClass("print");
µ('.positive').removeClass("positive");
µ('#renak').addClass("positive");
printTitle = `Rencana Aksi Agen Perubahan ${data.name} Tahun ${data.prokers[0].year}`;
});
µ('#eval').click(()=>{
µ('.viewer').prop("hidden",true);
µ('.viewer').removeClass("print");
µ('#vEval').prop("hidden",false);
µ('#vEval').addClass("print");
µ('.positive').removeClass("positive");
µ('#eval').addClass("positive");
printTitle = `Evaluasi Agen Perubahan ${data.name} Tahun ${data.prokers[0].year}`;
});
let str = "☆☆☆☆☆";
for(let s=1;s<=data.rating;s++)
{
str = "★" + str;
str = str.substring(0,5);
}
str += ` (${data.rating})`
µ('#rating').text(str);
µ('.yr').text(data.prokers[0].year);
µ('.name').text(data.name);
µ('.nip').text(data.agentID);
// const spv = agents.find(a=>a.agentID == data.prokers[0].journal.find(j=>j.status == 3).submitterID);
µ('.titles').text(spv.jabatan);
µ('.names').text(spv.name);
µ('.nips').text(spv.agentID);
const evd = data.prokers.find(p=>p.evaled)?.journal.find(j=>j.status == 8);
µ('#eval').prop("disabled", (!evd));
// const evr = agents.find(a=>a.agentID == evd?.submitterID);
µ('.dt').text((new Date()).getDate().toString().padStart(2,"0"));
µ('.mth').text(monthName[(new Date()).getMonth()+1]);
µ('.titlee').text(evr.jabatan);
µ('.namee').text(evr.name);
µ('.nipe').text(evr.agentID);
µ('.uk').text(data.unitKerja);
µ('.uk').text(data.unitKerja);
function populateReport()
{
µ('#pkContent').empty();
µ('#raContent').empty();
µ('#evContent').empty();
$.each(data.prokers,(i,v)=>{
const ro = moly.newElement("tr");
const no = moly.newElement("td");
const kg = moly.newElement("td");
const ss = moly.newElement("td");
const tg = moly.newElement("td");
const st = moly.newElement("td");
ro.append(no);
ro.append(kg);
ro.append(ss);
ro.append(tg);
ro.append(st);
no.style.textAlign
= "right";
tg.style.textAlign
= "center";
no.append((i+1)+".");
kg.append(kegiatanName[v.kegiatan]);
ss.append(v.sasaran);
tg.append(`${v.timeTarget} ${v.isInMonth ? "Bulan" : "Hari"}`);
// st.append(((v.startDay == null ? "" : v.startDay.toString().padStart(2,"0") + " ") + monthName[v.startMonth] + " " + v.year));
st.append((v.year+"/"+v.startMonth.toString().padStart(2,"0")) + (!v.isInMonth ? ("/"+v.startDay.toString().padStart(2,"0")) : ""));
µ('#pkContent').append(ro);
const rro = moly.newElement("tr");
const rno = moly.newElement("td");
const inv = moly.newElement("td");
const ssr = moly.newElement("td");
const ind = moly.newElement("td");
const tgt = moly.newElement("td");
const act = moly.newElement("td");
const str = moly.newElement("td");
const end = moly.newElement("td");
rro.append(rno);
rro.append(inv);
rro.append(ssr);
rro.append(ind);
rro.append(tgt);
rro.append(act);
rro.append(str);
rro.append(end);
rno.style.textAlign
="right";
tgt.style.textAlign
="center";
rno.append((i+1)+".");
inv.append(v.sasaran);
ssr.append(v.entityTarget);
ind.append(v.indicators);
tgt.append(`${v.timeTarget} ${v.isInMonth ? "Bulan" : "Hari"}`);
act.append(v.actions);
// str.append(((v.startDay == null ? "" : v.startDay.toString().padStart(2,"0") + " ") + monthName[v.startMonth] + " " + v.year));
str.append((v.year+"/"+v.startMonth.toString().padStart(2,"0")) + (!v.isInMonth ? ("/"+v.startDay.toString().padStart(2,"0")) : ""));
end.append(!v.completed ? "Belum" : v.journal.find(j=>j.status == 4).timeStamp.replaceAll("-","/").substring(0,10))
µ('#raContent').append(rro);
// if(!evd) return;
const ero = moly.newElement("tr");
const env = moly.newElement("td");
const ess = moly.newElement("td");
const ein = moly.newElement("td");
const etg = moly.newElement("td");
const eac = moly.newElement("td");
const est = moly.newElement("td");
const edn = moly.newElement("td");
const eks = moly.newElement("td");
const ems = moly.newElement("td");
const ert = moly.newElement("td");
ero.append(env);
ero.append(ess);
ero.append(ein);
ero.append(etg);
ero.append(eac);
ero.append(est);
ero.append(edn);
ero.append(eks);
ero.append(ems);
ero.append(ert);
env.append(v.sasaran);
ess.append(v.entityTarget);
ein.append(v.indicators);
etg.append(`${v.timeTarget} ${v.isInMonth ? "Bulan" : "Hari"}`);
eac.append(v.actions);
est.append((v.year+"/"+v.startMonth.toString().padStart(2,"0")) + (!v.isInMonth ? ("/"+v.startDay.toString().padStart(2,"0")) : ""));
edn.append(!v.completed ? "(Belum Selesai)" : v.journal.find(j=>j.status == 4).timeStamp.replaceAll("-","/").substring(0,10));
const done = v.completed ? v.journal.find(j=>j.status == 4) : {};
const ks = v.completed ? JSON.parse(done.notes) : {}
const ksstr = v.completed ? (
`Kendala:
${(ks.kendala.length > 0 ? ks.kendala : "-")}
Solusi:
${(ks.solusi.length > 0 ? ks.solusi : "-")}`
) : "(Belum Selesai)"
eks.append(ksstr);
eks.style.setProperty("white-space", "pre-line", "important");
const evalj = v.evaled ? v.journal.find(j=>j.status == 8) : {};
const ev = v.evaled ? JSON.parse(evalj.notes) : {m:"(Belum Evaluasi)",r:0}
ems.append(ev.m);
ert.append(ev.r);
µ('#evContent').append(ero);
})
}
populateReport();
µ('#proker').click();
µ('#print').click(()=>{
const content = µ('.print')[0];
if(!content) return;
const pw = window.open('', '_blank');
pw.document.write(`
<html>
<head>
<title>${printTitle}</title>
<link rel="stylesheet" href="/assets/css/fonts.css">
<link rel="stylesheet" href="/assets/css/molybdenum.css">
<style>
@page {
margin: 1cm;
size: A4 landscape;
}
body {
margin: 0;
padding: 0;
font-size: 10pt !important;
}
table.bordered tbody.signBlock td{
border: none;
}
table.bordered th , table.bordered td {
border: 1px solid var(--secondary-background);
font-size: 10pt !important;
}
table td {
white-space: normal !important;
overflow: visible !important;
text-overflow: unset !important;
}
.tbwrapper
{
overflow: unset !important;
max-height: unset !important;
}
tr {
break-inside: avoid;
}
</style>
</head>
<body>
${content.innerHTML}
<script>
requestAnimationFrame(() => {
setTimeout(() => {
window.print();
window.close();
}, 100); // small delay ensures DOM is painted
});
<\/script>
</body>
</html>
`);
pw.history.replaceState({}, "", "Laporan-Agen-Perubahan");
pw.document.close();
});
if (!units.status) moly.loadScreen.close(loadid);
</script>