Files
OBE-Mapping/app/templates/form_rps.html
T
Power BI Dev a45b08b00e Tambah peran Dosen MK/RPS+MK, komponen penilaian baku, dan bantu isi RPS
- Peran dosen dipecah jadi dosen_mk (nilai & portofolio saja, RPS baca-only)
  dan dosen_rps_mk (bisa edit RPS juga); migrasi otomatis dari skema lama.
- Rekap Bobot Penilaian RPS pakai 6 komponen teknik asesmen baku prodi;
  total wajib tepat 100%, komponen individual boleh dikosongkan.
- Dropdown & daftar Sub-CPMK tak lagi terpotong teksnya.
- Bagian F (Rencana Mingguan): tombol "Isi Otomatis" per baris (termasuk
  usulan Bobot) yang muncul setelah Sub-CPMK dipilih, plus panel contoh
  teks bantu per kolom.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 08:45:56 +07:00

284 lines
16 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block judul %}RPS {{ peta.nama }} — Informatika UNTAN{% endblock %}
{% block isi %}
<div class="nav-baris">
<div>MK ini: <b>RPS</b> · <a href="/nilai/{{ peta.kode }}">Input Nilai</a> · <a href="/portofolio/{{ peta.kode }}">Portofolio</a></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>Rencana Pembelajaran Semester — {{ 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 tidak memiliki hak edit RPS untuk MK ini — form terbuka
<b>hanya untuk dibaca</b>. Ini karena Anda bukan pengampu MK ini, atau peran Anda
<b>Dosen MK</b> (hanya mengelola nilai &amp; portofolio). Hubungi kaprodi bila ini
perlu diubah.</div>
{% endif %}
{% if tahun_lain and boleh_edit %}
<div class="info">
MK ini punya RPS pada tahun ajaran lain. Salin sebagai titik awal (status draft, bisa diedit):
{% for t in tahun_lain %}
<form method="post" action="/rps/{{ peta.kode }}/salin" style="display:inline">
<input type="hidden" name="dari" value="{{ t }}">
<button class="tombol garis" type="submit" style="padding:3px 10px;font-size:13px">Salin dari {{ t }}</button>
</form>
{% endfor %}
</div>
{% endif %}
<form method="post" action="/rps/{{ peta.kode }}">
<h2 class="bagian">A. IDENTITAS MATA KULIAH</h2>
<table class="grid">
<tr><td class="label">Nama Mata Kuliah</td><td>{{ peta.nama }}</td></tr>
<tr><td class="label">Kode Mata Kuliah</td><td>{{ peta.kode }}</td></tr>
<tr><td class="label">Bobot SKS</td>
<td class="isian" style="display:flex;gap:8px;align-items:center;border:none">
<input type="number" name="sks" min="0" max="8" style="width:70px" value="{{ f.identitas.sks }}"> SKS
&nbsp;(Teori: <input type="number" name="sks_teori" min="0" max="8" style="width:70px" value="{{ f.identitas.sks_teori }}">
| Praktikum: <input type="number" name="sks_praktikum" min="0" max="8" style="width:70px" value="{{ f.identitas.sks_praktikum }}">)
</td></tr>
<tr><td class="label">Semester</td><td class="isian"><input type="text" name="semester" value="{{ f.identitas.semester }}" placeholder="mis. 3 (Ganjil)"></td></tr>
<tr><td class="label">Rumpun MK</td><td class="isian"><input type="text" name="rumpun" value="{{ f.identitas.rumpun }}" placeholder="mis. MK Inti Keilmuan"></td></tr>
<tr><td class="label">MK Prasyarat</td><td class="isian"><input type="text" name="prasyarat" value="{{ f.identitas.prasyarat }}" placeholder="kosongkan bila tidak ada"></td></tr>
<tr><td class="label">Dosen Pengampu</td><td class="isian"><input type="text" name="pengampu" value="{{ f.identitas.pengampu }}" placeholder="Nama Dosen 1 | Nama Dosen 2"></td></tr>
<tr><td class="label">Dosen Pengembang RPS</td><td class="isian"><input type="text" name="pengembang" value="{{ f.identitas.pengembang }}" placeholder="bila kosong: diisi nama dosen pengampu"></td></tr>
<tr><td class="label">Koordinator MK</td><td class="isian"><input type="text" name="koordinator" value="{{ f.identitas.koordinator }}"></td></tr>
<tr><td class="label">Ketua Program Studi</td><td class="isian"><input type="text" name="kaprodi" value="{{ f.identitas.kaprodi }}"></td></tr>
<tr><td class="label">Tgl Penyusunan</td><td class="isian"><input type="text" name="tgl_penyusunan" value="{{ f.identitas.tgl_penyusunan }}" placeholder="mis. 13 Juli 2026"></td></tr>
<tr><td class="label">Kode Dokumen</td><td class="isian"><input type="text" name="kode_dokumen" value="{{ f.identitas.kode_dokumen }}" placeholder="diisi bagian penjaminan mutu, boleh kosong"></td></tr>
</table>
<h2 class="bagian">B. CPL YANG DIBEBANKAN PADA MK <span style="font-weight:normal;font-style:italic;color:var(--grey)">— otomatis dari pemetaan kurikulum</span></h2>
<table class="grid">
<thead><tr><th style="width:90px">Kode</th><th>Deskripsi CPL</th></tr></thead>
<tbody>
{% for c in peta.cpls %}
<tr><td class="tengah">{{ c.kode }}</td><td>{{ c.desk }}</td></tr>
{% endfor %}
</tbody>
</table>
<h2 class="bagian">C. CPMK <span style="font-weight:normal;font-style:italic;color:var(--grey)">— otomatis dari pemetaan kurikulum</span></h2>
<table class="grid">
<thead><tr><th style="width:110px">Kode</th><th>Deskripsi CPMK</th><th style="width:130px">CPL Didukung</th></tr></thead>
<tbody>
{% for c in peta.cpmks %}
<tr><td class="tengah">{{ c.kode }}</td><td>{{ c.desk }}</td><td class="tengah">{{ c.cpl|join(', ') }}</td></tr>
{% endfor %}
</tbody>
</table>
<h2 class="bagian">D. SUB-CPMK <span style="font-weight:normal;font-style:italic;color:var(--grey)">— otomatis dari pemetaan kurikulum ({{ peta.subs|length }} butir)</span></h2>
<div class="gulir" style="max-height:320px;overflow-y:auto">
<table class="grid">
<thead><tr><th style="width:110px">Kode</th><th>Uraian Sub-CPMK</th><th style="width:110px">CPMK</th></tr></thead>
<tbody>
{% for s in peta.subs %}
<tr><td class="tengah">{{ s.kode }}</td><td>{{ s.uraian }}</td><td class="tengah">{{ s.cpmk }}</td></tr>
{% endfor %}
</tbody>
</table>
</div>
<h2 class="bagian">E. DESKRIPSI SINGKAT MATA KULIAH</h2>
<textarea name="deskripsi" rows="4" placeholder="Topik utama, pendekatan pembelajaran, relevansi dengan profil lulusan dan CPL. Maksimal ± 100 kata.">{{ f.deskripsi }}</textarea>
<h2 class="bagian">E2. BAHAN KAJIAN — MATERI PEMBELAJARAN</h2>
<textarea name="bahan_kajian" rows="4" placeholder="Materi/bahan kajian MK secara berurutan (sesuai format RPS UNTAN).">{{ f.bahan_kajian }}</textarea>
<h2 class="bagian">E3. MEDIA PEMBELAJARAN</h2>
<textarea name="media" rows="2" placeholder="mis. LMS (e-learning UNTAN), LCD proyektor, perangkat lunak pendukung.">{{ f.media }}</textarea>
<h2 class="bagian">F. RENCANA MINGGUAN <span id="total-bobot-f" style="font-weight:normal">— total bobot: <b>0</b>%</span></h2>
<p class="keterangan">Minggu 8 = UTS, minggu 16 = UAS. Total bobot seluruh minggu harus 100 %.
{% if boleh_edit %}Pilih Sub-CPMK lalu klik <b>Isi Otomatis</b> untuk mengisi kolom kosong dengan teks
bantu (termasuk usulan Bobot — UTS 20%, UAS 30%, minggu biasa 3,5% — sesuaikan lagi agar totalnya
pas 100%).{% endif %}</p>
{% if boleh_edit %}
<details style="margin:0 0 10px">
<summary style="cursor:pointer;color:var(--blue);font-size:13px">Lihat contoh teks bantu per kolom</summary>
<div class="info" style="margin-top:6px;line-height:1.7">
<b>Indikator</b> — turunan Sub-CPMK, mis. "Mahasiswa mampu menjelaskan …"; "Ketepatan dan kelengkapan dalam …"<br>
<b>Kriteria &amp; Teknik</b> — mis. "Rubrik holistik; tes tertulis" / "Ketepatan jawaban; unjuk kerja" / "Kelengkapan tugas; observasi"<br>
<b>Tatap Muka</b> — mis. "Ceramah, diskusi, tanya jawab [TM: 2x50 menit]" / "Studi kasus &amp; presentasi kelompok [TM: 2x50 menit]"<br>
<b>Daring</b> — mis. "Membaca modul &amp; kuis di LMS [BT+BM: 2x60 menit]" / "Diskusi forum LMS [BT+BM: 2x60 menit]"<br>
<b>Kegiatan Pembelajaran</b> — mis. "Mahasiswa menyimak paparan dosen, berdiskusi, dan mengerjakan latihan terkait materi minggu ini."<br>
<b>Materi [Pustaka]</b> — rujuk nomor pustaka di Bagian H, mis. "Bab 3 (Pustaka Utama #1)"
</div>
</details>
{% endif %}
<div class="gulir">
<table class="grid" id="tabel-f">
<thead>
<tr>
<th class="tengah" style="width:52px" rowspan="2">Mg</th>
<th style="min-width:190px" rowspan="2">Sub-CPMK</th>
<th colspan="2">Penilaian</th>
<th colspan="2">Bentuk/Metode Pembelajaran [Estimasi Waktu]</th>
<th style="min-width:140px" rowspan="2">Kegiatan Pembelajaran</th>
<th style="min-width:150px" rowspan="2">Materi [Pustaka]</th>
<th class="tengah" style="width:70px" rowspan="2">Bobot (%)</th>
</tr>
<tr>
<th class="sub" style="min-width:150px">Indikator</th>
<th class="sub" style="min-width:140px">Kriteria &amp; Teknik</th>
<th class="sub" style="min-width:130px">Tatap Muka</th>
<th class="sub" style="min-width:120px">Daring</th>
</tr>
</thead>
<tbody>
{% for m in f.minggu %}
<tr class="{% if m.ke == 8 %}uts{% elif m.ke == 16 %}uas{% endif %}">
<td class="tengah">{{ m.ke }}</td>
<td class="isian">
<select name="m{{ m.ke }}_sub" {% if boleh_edit %}onchange="document.getElementById('btn-isi-m{{ m.ke }}').style.display = this.value ? '' : 'none'"{% endif %}>
<option value="">— pilih —</option>
{% for s in peta.subs %}
<option value="{{ s.kode }}" {% if m.sub == s.kode %}selected{% endif %}>{{ s.kode }} — {{ s.uraian }}</option>
<option disabled>──────────────────────</option>
{% endfor %}
<option value="__uts__" {% if m.sub == '__uts__' %}selected{% endif %}>Sub-CPMK minggu 17 (UTS)</option>
<option value="__uas__" {% if m.sub == '__uas__' %}selected{% endif %}>Sub-CPMK minggu 915 (UAS)</option>
</select>
{% if boleh_edit %}
<button type="button" id="btn-isi-m{{ m.ke }}" class="tombol garis"
style="padding:1px 6px;font-size:10px;margin-top:4px;{% if not m.sub %}display:none{% endif %}"
onclick="isiOtomatis({{ m.ke }})" title="Isi kolom kosong dengan teks bantu dari Sub-CPMK terpilih">Isi Otomatis</button>
{% endif %}
</td>
<td class="isian"><textarea name="m{{ m.ke }}_indikator" rows="2">{{ m.indikator }}</textarea></td>
<td class="isian"><textarea name="m{{ m.ke }}_kriteria" rows="2">{{ m.kriteria }}</textarea></td>
<td class="isian"><textarea name="m{{ m.ke }}_metode" rows="2">{{ m.metode }}</textarea></td>
<td class="isian"><textarea name="m{{ m.ke }}_daring" rows="2">{{ m.daring }}</textarea></td>
<td class="isian"><textarea name="m{{ m.ke }}_kegiatan" rows="2">{{ m.kegiatan }}</textarea></td>
<td class="isian"><textarea name="m{{ m.ke }}_materi" rows="2">{{ m.materi }}</textarea></td>
<td class="isian"><input type="number" class="bobot-f" name="m{{ m.ke }}_bobot" min="0" max="100" step="0.5" value="{{ m.bobot }}"></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<h2 class="bagian">G. REKAP BOBOT PENILAIAN <span id="total-bobot-g" style="font-weight:normal">— total: <b>0</b>%</span></h2>
<p class="keterangan">Enam komponen teknik asesmen baku prodi. Bobot boleh dikosongkan untuk
komponen yang tidak dipakai MK ini (opsional), tapi total seluruh komponen yang diisi harus
tepat 100%. Centang Sub-CPMK yang dinilai tiap komponen; setiap Sub-CPMK harus tercakup minimal
satu komponen agar CPMK/CPL-nya terukur.</p>
<div class="gulir">
<table class="grid">
<thead>
<tr><th style="width:190px">Komponen</th><th>Sub-CPMK yang Dinilai</th><th class="tengah" style="width:90px">Bobot (%)</th></tr>
</thead>
<tbody>
{% for k in f.komponen %}
{% set ki = loop.index %}
<tr>
<td>{{ k.nama }}</td>
<td>
<div class="pilih-sub">
{% for s in peta.subs %}
<label><input type="checkbox" class="sub-k" name="k{{ ki }}_subs" value="{{ s.kode }}" {% if s.kode in k.subs %}checked{% endif %}>{{ s.kode }} — {{ s.uraian }}</label>
{% endfor %}
</div>
</td>
<td class="isian"><input type="number" class="bobot-g" name="k{{ ki }}_bobot" min="0" max="100" step="0.5" value="{{ k.bobot }}"></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="info" id="cek-cakupan" hidden></div>
<h2 class="bagian">H. PUSTAKA UTAMA</h2>
<p class="keterangan">Satu referensi per baris, format APA.</p>
<textarea name="referensi" rows="5" placeholder="Penulis. (Tahun). Judul. Penerbit / Jurnal, Vol(No), Hal. https://doi.org/...">{{ f.referensi_teks }}</textarea>
<h2 class="bagian">H2. PUSTAKA PENDUKUNG</h2>
<textarea name="referensi_pendukung" rows="3" placeholder="Satu referensi per baris; boleh kosong.">{{ f.referensi_pendukung_teks }}</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 &amp; Tandai Selesai</button>
{% else %}
<span class="spacer"></span>
{% endif %}
{% if status %}<a class="tombol" href="/rps/{{ peta.kode }}/unduh">Unduh .docx</a>
<a class="tombol garis" href="/rps/{{ peta.kode }}/unduh.pdf">PDF</a>{% endif %}
</div>
</form>
<script>
const SUB_URAIAN = {{ sub_uraian | tojson | safe }};
function isiOtomatis(mg) {
const sel = document.querySelector(`select[name="m${mg}_sub"]`);
const nilai = sel ? sel.value : '';
const isi = (nama, teks) => {
const el = document.querySelector(`[name="m${mg}_${nama}"]`);
if (el && !el.value.trim()) el.value = teks;
};
if (SUB_URAIAN[nilai]) {
const uraian = SUB_URAIAN[nilai];
isi('indikator', 'Mahasiswa ' + uraian.charAt(0).toLowerCase() + uraian.slice(1));
} else if (nilai === '__uts__') {
isi('indikator', 'Mahasiswa menguasai capaian Sub-CPMK minggu 17.');
} else if (nilai === '__uas__') {
isi('indikator', 'Mahasiswa menguasai capaian Sub-CPMK minggu 915.');
} else {
return; // belum pilih Sub-CPMK — tak ada dasar untuk mengisi
}
isi('kriteria', 'Ketepatan dan kelengkapan jawaban/tugas sesuai rubrik penilaian.');
isi('metode', 'Ceramah, diskusi, dan tanya jawab [TM: 2x50 menit]');
isi('daring', 'Membaca materi & berdiskusi di LMS [BT+BM: 2x60 menit]');
isi('kegiatan', 'Mahasiswa menyimak penjelasan dosen, berdiskusi, dan mengerjakan latihan terkait materi minggu ini.');
// bobot: usulan awal (UTS/UAS lazim lebih besar) — total tetap harus disesuaikan ke 100%
isi('bobot', mg == 8 ? '20' : mg == 16 ? '30' : '3.5');
segarkan();
}
function hitungTotal(kelas, idLabel) {
let t = 0;
document.querySelectorAll(kelas).forEach(el => { t += parseFloat(el.value) || 0; });
const label = document.querySelector(idLabel);
label.querySelector('b').textContent = (Math.round(t * 100) / 100);
label.classList.toggle('salah', Math.abs(t - 100) > 0.01);
}
function cekCakupan() {
const dinilai = new Set();
document.querySelectorAll('.sub-k:checked').forEach(cb => dinilai.add(cb.value));
const semua = [{% for s in peta.subs %}'{{ s.kode }}'{% if not loop.last %},{% endif %}{% endfor %}];
const hilang = semua.filter(k => !dinilai.has(k));
const kotak = document.getElementById('cek-cakupan');
if (hilang.length === 0) {
kotak.hidden = false;
kotak.className = 'info';
kotak.textContent = 'Semua ' + semua.length + ' Sub-CPMK sudah tercakup komponen penilaian — CPMK dan CPL mata kuliah ini akan terukur penuh.';
} else {
kotak.hidden = false;
kotak.className = 'peringatan';
kotak.textContent = 'Perhatian: ' + hilang.length + ' Sub-CPMK belum dinilai komponen mana pun (ketercapaian CPMK/CPL-nya tidak akan terukur): ' + hilang.join(', ');
}
}
function segarkan() {
hitungTotal('.bobot-f', '#total-bobot-f');
hitungTotal('.bobot-g', '#total-bobot-g');
cekCakupan();
}
document.addEventListener('input', segarkan);
segarkan();
</script>
{% endblock %}