5d7ab16733
- Portofolio: section "Analisis Proses Asesmen" (dropdown tertutup default) — distribusi huruf mutu, kelompok capaian (mean ± SD), Sub-CPMK terlemah/terkuat, kesenjangan rencana vs realisasi, mahasiswa berisiko, tren lintas tahun ajaran - Portofolio: Nomor Dokumen & Tanggal Terbit terisi otomatis; placeholder contoh di Realisasi Pembelajaran dan Kendala & Tindak Lanjut; tombol "Isi Otomatis" merangkai draf Simpulan dari analisis + realisasi + kendala - Nilai: tabel Kelompok Capaian (Atas/Tengah/Bawah, shading warna) dipindah ke dropdown "Detail Tambahan" bersama Skala Poin/Rincian Bobot/Hasil Ketercapaian; tabel utama tak lagi ada scroll vertikal internal - Nilai: riwayat pengisian dicatat terstruktur (waktu, dosen, aksi, komponen), tanpa batas 8 entri, dengan ringkasan per komponen + dropdown Log Lengkap — mendukung akuntabilitas team teaching - Fix bug data: seed kurikulum menyimpan 'cpl' CPMK sebagai string tunggal, bukan list, sehingga pecah per huruf saat di-join() di tabel Hasil Ketercapaian/Rekap (mis. "CPL-03" -> "C, P, L, -, 0, 3"); dinormalisasi di db.py (runtime) dan tools/extract_seed.py (agar re-seed berikutnya benar) - Hover tooltip deskripsi lengkap di kode Sub-CPMK/CPMK/CPL (halaman Nilai dan Rekap CPL/CPMK) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
219 lines
13 KiB
HTML
219 lines
13 KiB
HTML
{% extends "base.html" %}
|
||
{% block judul %}Portofolio {{ peta.nama }} — Informatika UNTAN{% endblock %}
|
||
{% block isi %}
|
||
<div class="nav-baris">
|
||
<div>MK ini: <a href="/rps/{{ peta.kode }}">RPS</a> · <a href="/rps/{{ peta.kode }}/rtm">RTM</a> · <a href="/nilai/{{ peta.kode }}">Input Nilai</a> · <b>Portofolio</b></div>
|
||
<div>
|
||
{% if status == 'selesai' %}<span class="stamp stamp-ok">SELESAI</span>
|
||
{% elif status == 'draft' %}<span class="stamp stamp-draft">DRAFT</span>
|
||
{% else %}<span class="stamp stamp-no">BELUM</span>{% endif %}
|
||
{% if updated_at %}<span style="color:var(--grey);font-size:13px"> · disimpan {{ updated_at }}{% if updated_by %} oleh {{ updated_by }}{% endif %}</span>{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<h1>Portofolio Mata Kuliah — {{ peta.nama }} <span style="color:var(--grey)">({{ peta.kode }})</span></h1>
|
||
|
||
{% if pesan %}<div class="info">{{ pesan }}</div>{% endif %}
|
||
|
||
{% if not boleh_edit %}
|
||
<div class="info">Anda bukan pengampu MK ini — form terbuka <b>hanya untuk dibaca</b>;
|
||
unduhan dokumen (memuat nilai mahasiswa) juga dibatasi untuk pengampu dan kaprodi.</div>
|
||
{% endif %}
|
||
|
||
{% if not ada_rps %}
|
||
<div class="peringatan">RPS MK ini belum disusun — bagian Rencana Penilaian, korelasi bobot, dan nilai akhir tertimbang akan kosong. <a href="/rps/{{ peta.kode }}">Susun RPS dulu →</a></div>
|
||
{% endif %}
|
||
{% if not ada_nilai %}
|
||
<div class="peringatan">Nilai MK ini belum diinput — bagian Penilaian, Evaluasi Ketercapaian, dan Simpulan statistik akan kosong. <a href="/nilai/{{ peta.kode }}">Input nilai dulu →</a></div>
|
||
{% endif %}
|
||
{% if ada_rps and ada_nilai %}
|
||
<div class="info">RPS ✓ dan Nilai ✓ tersedia — tabel korelasi, penilaian, evaluasi ketercapaian, dan statistik akan diisi otomatis di dokumen. Anda hanya melengkapi bagian di bawah.</div>
|
||
{% endif %}
|
||
|
||
{% if analisis %}
|
||
<details class="cara-alt" style="margin-top:26px;border:1px solid #c9c9c9;padding:10px 14px">
|
||
<summary>ANALISIS PROSES ASESMEN {% if analisis.berisiko %}<span style="color:var(--red);font-weight:normal;font-size:13px">— {{ analisis.berisiko|length }} mahasiswa berisiko</span>{% endif %}</summary>
|
||
<p class="keterangan">Dihitung otomatis dari RPS + Nilai tersimpan — bahan diskusi sebelum menulis Realisasi & Simpulan di bawah. Hanya tampil di layar, tidak ikut ke dokumen unduhan.</p>
|
||
|
||
<div class="perhatian-kisi">
|
||
<div>
|
||
<p class="keterangan" style="margin-top:0">Distribusi huruf mutu{% if analisis.statistik %} ({{ analisis.statistik.n }} mahasiswa){% endif %}</p>
|
||
{% if analisis.statistik %}
|
||
<table class="grid">
|
||
<thead><tr><th>Huruf</th><th class="tengah">Jumlah</th><th class="tengah">%</th></tr></thead>
|
||
<tbody>
|
||
{% for h, n in analisis.statistik.frekuensi.items() %}
|
||
<tr><td>{{ h }}</td><td class="tengah">{{ n }}</td>
|
||
<td class="tengah">{{ '%.0f'|format(100 * n / analisis.statistik.n) }}%</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
<p class="keterangan">Rata-rata {{ '%.1f'|format(analisis.statistik.mean) }} · median {{ '%.1f'|format(analisis.statistik.median) }} · rentang {{ '%.1f'|format(analisis.statistik.min) }}–{{ '%.1f'|format(analisis.statistik.max) }}</p>
|
||
{% if analisis.kelompok %}
|
||
<p class="keterangan">Kelompok capaian (mean ± SD, batas {{ '%.1f'|format(analisis.kelompok.batas_bawah) }}–{{ '%.1f'|format(analisis.kelompok.batas_atas) }}):
|
||
<b style="color:#205020">Atas {{ analisis.kelompok.atas|length }}</b> ·
|
||
Tengah {{ analisis.kelompok.tengah|length }} ·
|
||
<b style="color:var(--red)">Bawah {{ analisis.kelompok.bawah|length }}</b>{% if analisis.kelompok.bawah %} ({{ analisis.kelompok.bawah|map(attribute='nama')|join(', ') }}){% endif %}</p>
|
||
{% endif %}
|
||
{% else %}
|
||
<p class="keterangan">Nilai masih mode agregat (rata-rata kelas) — distribusi huruf per mahasiswa tidak bisa dihitung.</p>
|
||
{% endif %}
|
||
</div>
|
||
<div>
|
||
<p class="keterangan" style="margin-top:0">Sub-CPMK terlemah & terkuat</p>
|
||
{% if analisis.sub_urut %}
|
||
<table class="grid">
|
||
<thead><tr><th>Sub-CPMK</th><th class="tengah">Skor</th><th class="tengah">Lulus %</th></tr></thead>
|
||
<tbody>
|
||
{% for s in analisis.sub_urut %}
|
||
<tr><td>{{ s.kode }} — {{ s.uraian }}</td>
|
||
<td class="tengah"{% if s.rata < analisis.ambang %} style="color:var(--red)"{% endif %}>{{ '%.1f'|format(s.rata) }}</td>
|
||
<td class="tengah">{{ '%.0f'|format(s.lulus_pct) if s.lulus_pct is not none else '—' }}{% if s.lulus_pct is not none %}%{% endif %}</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p class="keterangan">Belum ada Sub-CPMK ternilai.</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
{% if analisis.kesenjangan %}
|
||
<p class="keterangan" style="margin-top:14px"><b>Kesenjangan rencana vs realisasi:</b> {{ analisis.kesenjangan|length }} Sub-CPMK diberi bobot di RPS tapi belum ada nilai masuk — {{ analisis.kesenjangan|join(', ') }}.</p>
|
||
{% endif %}
|
||
|
||
{% if analisis.berisiko %}
|
||
<p class="keterangan" style="margin-top:14px">Mahasiswa berisiko — ≥2 Sub-CPMK di bawah ambang ({{ analisis.ambang|int }}), atau nilai akhir sendiri di bawahnya</p>
|
||
<table class="grid">
|
||
<thead><tr><th>NIM</th><th>Nama</th><th class="tengah">Sub-CPMK di bawah ambang</th><th class="tengah">Nilai Akhir</th></tr></thead>
|
||
<tbody>
|
||
{% for m in analisis.berisiko %}
|
||
<tr><td>{{ m.nim }}</td><td>{{ m.nama }}</td>
|
||
<td class="tengah">{{ m.n_dibawah }}/{{ m.total_sub }}</td>
|
||
<td class="tengah" style="color:var(--red)">{{ '%.1f'|format(m.akhir) if m.akhir is not none else '—' }}</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% endif %}
|
||
|
||
{% if analisis.tren %}
|
||
<p class="keterangan" style="margin-top:14px">Tren MK ini lintas tahun ajaran — apakah capaian membaik atau tidak</p>
|
||
<table class="grid">
|
||
<thead><tr><th>Tahun Ajaran</th><th class="tengah">Rata-rata</th><th class="tengah">% Kelulusan</th><th class="tengah">n Mahasiswa</th></tr></thead>
|
||
<tbody>
|
||
{% for t in analisis.tren %}
|
||
<tr{% if t.tahun == tahun %} class="total"{% endif %}>
|
||
<td>{{ t.tahun }}</td>
|
||
<td class="tengah">{{ '%.1f'|format(t.mean) if t.mean is not none else '—' }}</td>
|
||
<td class="tengah">{{ '%.0f'|format(t.lulus_pct) if t.lulus_pct is not none else '—' }}{% if t.lulus_pct is not none %}%{% endif %}</td>
|
||
<td class="tengah">{{ t.n if t.n is not none else '—' }}</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% endif %}
|
||
</details>
|
||
{% endif %}
|
||
|
||
<form method="post" action="/portofolio/{{ peta.kode }}">
|
||
<h2 class="bagian">IDENTITAS DOKUMEN (LEMBAR PENGESAHAN)</h2>
|
||
<table class="grid">
|
||
<tr><td class="label">Nomor Dokumen</td><td class="isian"><input type="text" name="nomor" value="{{ f.dokumen.nomor }}" placeholder="mis. PORTO/INF/2026/001 — boleh kosong"></td></tr>
|
||
<tr><td class="label">No. Revisi</td><td class="isian"><input type="text" name="revisi" value="{{ f.dokumen.revisi }}"></td></tr>
|
||
<tr><td class="label">Tanggal Terbit</td><td class="isian"><input type="text" name="tgl_terbit" value="{{ f.dokumen.tgl_terbit }}" placeholder="mis. 20 Desember 2026"></td></tr>
|
||
<tr><td class="label">Kurikulum Tahun</td><td class="isian"><input type="text" name="kurikulum_tahun" value="{{ f.dokumen.kurikulum_tahun }}"></td></tr>
|
||
<tr><td class="label">Nama Dekan</td><td class="isian"><input type="text" name="dekan" value="{{ f.dokumen.dekan }}" placeholder="untuk kolom pengesahan"></td></tr>
|
||
<tr><td class="label">Status Dokumen</td>
|
||
<td class="isian">
|
||
<select name="status_dokumen" style="width:auto">
|
||
<option {% if f.dokumen.status_dokumen == 'Master' %}selected{% endif %}>Master</option>
|
||
<option {% if f.dokumen.status_dokumen == 'Copy' %}selected{% endif %}>Copy</option>
|
||
</select>
|
||
</td></tr>
|
||
</table>
|
||
|
||
<h2 class="bagian">REALISASI PEMBELAJARAN</h2>
|
||
<p class="keterangan">Ceritakan pelaksanaan nyata semester ini: penyesuaian jadwal/materi/metode terhadap rencana di RPS, kehadiran, dan hal penting lain.</p>
|
||
<textarea name="realisasi" rows="6" placeholder="Contoh: - Materi minggu 5–6 (rekursi) tertunda 1 minggu karena libur nasional, digabung jadi 1 pertemuan - Praktikum awalnya direncanakan luring, dialihkan ke daring minggu 3–4 karena lab dalam perbaikan - Rata-rata kehadiran mahasiswa, jumlah pertemuan efektif dari 16 minggu rencana - Metode yang berubah di lapangan (mis. tugas kelompok jadi individu karena jumlah mahasiswa sedikit)">{{ f.realisasi }}</textarea>
|
||
|
||
<h2 class="bagian">KENDALA & TINDAK LANJUT</h2>
|
||
{% set contoh_kendala = [
|
||
"Banyak mahasiswa kesulitan di konsep rekursi (Sub-CPMK X)",
|
||
"Partisipasi diskusi daring rendah",
|
||
"Jadwal praktikum bentrok dengan MK lain"] %}
|
||
{% set contoh_tindak = [
|
||
"Ditambah sesi responsi/tutorial tambahan minggu 9",
|
||
"Kuis singkat wajib tiap sesi untuk dorong keterlibatan",
|
||
"Diusulkan penyesuaian jadwal ke prodi semester depan"] %}
|
||
<table class="grid">
|
||
<thead><tr><th style="width:50px" class="tengah">No.</th><th>Kendala</th><th>Tindak Lanjut</th></tr></thead>
|
||
<tbody>
|
||
{% for k in f.kendala[:5] %}
|
||
<tr>
|
||
<td class="tengah">{{ loop.index }}</td>
|
||
<td class="isian"><textarea name="kendala_{{ loop.index }}" rows="2" placeholder="{{ contoh_kendala[loop.index0] if loop.index0 < contoh_kendala|length else '' }}">{{ k.kendala }}</textarea></td>
|
||
<td class="isian"><textarea name="tindak_{{ loop.index }}" rows="2" placeholder="{{ contoh_tindak[loop.index0] if loop.index0 < contoh_tindak|length else '' }}">{{ k.tindak }}</textarea></td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
|
||
<h2 class="bagian">SIMPULAN HASIL EVALUASI</h2>
|
||
<p class="keterangan">Statistik nilai, frekuensi huruf mutu, dan tabel ketercapaian CPL/CPMK dihitung dan dicetak otomatis; tuliskan simpulan naratifnya di sini.
|
||
{% if boleh_edit %}<button type="button" class="tombol garis" style="padding:2px 10px;font-size:12px" onclick="isiSimpulanOtomatis()">Isi Otomatis</button>
|
||
merangkai draf dari Analisis Proses Asesmen, Realisasi Pembelajaran, dan Kendala & Tindak Lanjut di atas — cek & lengkapi sebelum menyimpan.{% endif %}</p>
|
||
<textarea name="simpulan" rows="4">{{ f.simpulan }}</textarea>
|
||
|
||
<div class="aksi-baris">
|
||
{% if boleh_edit %}
|
||
<span style="color:var(--grey);font-size:13px">Disimpan atas nama <b>{{ user.nama }}</b></span>
|
||
<span class="spacer"></span>
|
||
<button class="tombol garis" type="submit" name="aksi" value="draft">Simpan Draft</button>
|
||
<button class="tombol selesai" type="submit" name="aksi" value="selesai">Simpan & Tandai Selesai</button>
|
||
{% if status %}<a class="tombol" href="/portofolio/{{ peta.kode }}/unduh">Unduh .docx</a>
|
||
<a class="tombol garis" href="/portofolio/{{ peta.kode }}/unduh.pdf">PDF</a>{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
</form>
|
||
|
||
<script>
|
||
const SIMPULAN_SARAN = {% if analisis %}{{ analisis.simpulan_saran | tojson | safe }}{% else %}null{% endif %};
|
||
|
||
// ambil kalimat pertama (maks `maks` karakter) dari teks bebas — dipakai
|
||
// untuk mengutip cuplikan Realisasi/Kendala ke dalam draf Simpulan
|
||
function ringkas(teks, maks) {
|
||
maks = maks || 160;
|
||
const kalimat = teks.match(/^.*?[.!?](?=\s|$)/);
|
||
let dasar = kalimat ? kalimat[0].trim() : teks.trim();
|
||
if (dasar.length > maks) dasar = teks.trim().slice(0, maks).trim() + '…';
|
||
return /[.!?…]$/.test(dasar) ? dasar : dasar + '.';
|
||
}
|
||
|
||
function isiSimpulanOtomatis() {
|
||
const bagian = [];
|
||
if (SIMPULAN_SARAN) bagian.push(SIMPULAN_SARAN);
|
||
|
||
const elRealisasi = document.querySelector('[name="realisasi"]');
|
||
const realisasi = elRealisasi ? elRealisasi.value.trim() : '';
|
||
if (realisasi) bagian.push('Dari sisi pelaksanaan pembelajaran: ' + ringkas(realisasi));
|
||
|
||
const kendalaTeks = [];
|
||
document.querySelectorAll('[name^="kendala_"]').forEach(el => {
|
||
const v = el.value.trim();
|
||
if (v) kendalaTeks.push(v);
|
||
});
|
||
if (kendalaTeks.length) {
|
||
const label = kendalaTeks.length > 1
|
||
? kendalaTeks.length + ' kendala tercatat, utamanya'
|
||
: 'Kendala utama yang tercatat';
|
||
bagian.push(label + ': ' + ringkas(kendalaTeks[0])
|
||
+ ' Tindak lanjutnya sudah direncanakan pada tabel Kendala & Tindak Lanjut di atas.');
|
||
}
|
||
|
||
if (!bagian.length) {
|
||
bagian.push('Belum ada data Analisis Proses Asesmen, Realisasi Pembelajaran, atau Kendala untuk dirangkai — isi bagian-bagian tersebut dulu, lalu klik Isi Otomatis lagi.');
|
||
}
|
||
document.querySelector('textarea[name="simpulan"]').value = bagian.join(' ');
|
||
}
|
||
</script>
|
||
{% endblock %}
|