|
|
|
@@ -0,0 +1,213 @@
|
|
|
|
|
{% extends "base.html" %}
|
|
|
|
|
{% block judul %}RTM {{ peta.nama }} — Informatika UNTAN{% endblock %}
|
|
|
|
|
{% block isi %}
|
|
|
|
|
<div class="nav-baris">
|
|
|
|
|
<div>MK ini: <a href="/rps/{{ peta.kode }}">RPS</a> · <b>RTM</b> · <a href="/nilai/{{ peta.kode }}">Input Nilai</a> · <a href="/portofolio/{{ peta.kode }}">Portofolio</a></div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<h1>Rencana Tugas Mandiri — {{ peta.nama }} <span style="color:var(--grey)">({{ peta.kode }})</span></h1>
|
|
|
|
|
|
|
|
|
|
<p class="keterangan">Dokumen RTM (Rancangan Tugas Mahasiswa) resmi sesuai format baku prodi —
|
|
|
|
|
<b>berdiri sendiri, tak ada kaitan apa pun dengan Nilai</b> (tidak memuat skor/nilai mahasiswa
|
|
|
|
|
sama sekali, murni dokumentasi rencana tugas MK ini). Tambah blok Tugas sesuai kebutuhan,
|
|
|
|
|
isi, lalu unduh sebagai satu berkas .docx.</p>
|
|
|
|
|
{% if rtm_updated_at %}<p class="keterangan" style="margin-top:-6px">Terakhir disimpan {{ rtm_updated_at }}{% if rtm_updated_by %} oleh {{ rtm_updated_by }}{% endif %}.</p>{% endif %}
|
|
|
|
|
|
|
|
|
|
{% 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>.</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
<form method="post" action="/rps/{{ peta.kode }}/rtm" id="form-rtm">
|
|
|
|
|
<fieldset {% if not boleh_edit %}disabled{% endif %} style="border:none;padding:0;margin:0">
|
|
|
|
|
<div id="daftar-tugas-rtm"></div>
|
|
|
|
|
<button type="button" class="tombol garis" onclick="tambahTugasRtm()">+ Tambah Tugas</button>
|
|
|
|
|
</fieldset>
|
|
|
|
|
<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" type="submit">Simpan RTM</button>
|
|
|
|
|
{% else %}
|
|
|
|
|
<span class="spacer"></span>
|
|
|
|
|
{% endif %}
|
|
|
|
|
<a class="tombol garis" href="/rps/{{ peta.kode }}/rtm/unduh">Unduh RTM (.docx)</a>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
|
|
<div style="text-align:center;margin-top:16px">
|
|
|
|
|
<button type="button" class="tombol garis" onclick="window.scrollTo({top:0, behavior:'smooth'})">▲ Ke Atas</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script id="tpl-tugas-rtm" type="text/template">
|
|
|
|
|
<details style="margin-bottom:12px;border:1px solid var(--border);border-radius:6px;padding:10px 14px">
|
|
|
|
|
<summary style="cursor:pointer;font-weight:bold"><span class="nomor-tugas-rtm">Tugas</span>
|
|
|
|
|
<button type="button" class="tombol garis" style="padding:0 8px;font-size:11px;color:var(--red);border-color:var(--red);float:right"
|
|
|
|
|
onclick="event.preventDefault(); hapusTugasRtm(this)">Hapus Tugas Ini</button>
|
|
|
|
|
</summary>
|
|
|
|
|
<div style="margin-top:12px">
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Judul Tugas
|
|
|
|
|
<input type="text" name="judul___IDX__" style="display:block;margin-top:4px;max-width:480px">
|
|
|
|
|
</label>
|
|
|
|
|
<div style="margin-bottom:10px">
|
|
|
|
|
<div>Sub Capaian Pembelajaran Mata Kuliah yang Dicapai <span style="font-weight:normal;color:var(--grey)">(opsional — untuk keterlacakan dokumen saja, tak memengaruhi nilai)</span></div>
|
|
|
|
|
<div class="pilih-sub">
|
|
|
|
|
{% for s in peta.subs %}
|
|
|
|
|
<label><input type="checkbox" name="subs___IDX__" value="{{ s.kode }}">{{ s.kode }} — {{ s.uraian }}</label>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Bentuk Tugas
|
|
|
|
|
<span style="display:flex;align-items:center;gap:8px;margin-top:4px">
|
|
|
|
|
<select name="bentuk_tugas___IDX__" id="bentuk_tugas___IDX__" onchange="toggleIsiOtomatisRtm('__IDX__')" style="max-width:280px">
|
|
|
|
|
<option value="">— pilih —</option>
|
|
|
|
|
{% for opsi in ["Diskusi", "PjBL", "CBL", "Esai", "Tes"] %}
|
|
|
|
|
<option value="{{ opsi }}">{{ opsi }}</option>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
</select>
|
|
|
|
|
<button type="button" class="tombol garis" id="tombol_isi_otomatis___IDX__"
|
|
|
|
|
onclick="isiOtomatisRtm('__IDX__')" hidden>Isi Otomatis</button>
|
|
|
|
|
</span>
|
|
|
|
|
</label>
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Deskripsi Tugas
|
|
|
|
|
<textarea name="deskripsi___IDX__" id="rtm_deskripsi___IDX__" rows="4" style="display:block;margin-top:4px;max-width:760px;width:100%"></textarea>
|
|
|
|
|
</label>
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Metode Pengerjaan Tugas
|
|
|
|
|
<textarea name="metode_pengerjaan___IDX__" id="rtm_metode___IDX__" rows="3" style="display:block;margin-top:4px;max-width:760px;width:100%"></textarea>
|
|
|
|
|
</label>
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Bentuk dan Format Luaran
|
|
|
|
|
<textarea name="luaran___IDX__" id="rtm_luaran___IDX__" rows="2" style="display:block;margin-top:4px;max-width:760px;width:100%"></textarea>
|
|
|
|
|
</label>
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Indikator, Kriteria dan Bobot Penilaian
|
|
|
|
|
<textarea name="indikator_bobot___IDX__" id="rtm_indikator___IDX__" rows="4" style="display:block;margin-top:4px;max-width:760px;width:100%"></textarea>
|
|
|
|
|
</label>
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Jadwal Pelaksanaan
|
|
|
|
|
<span style="display:flex;gap:16px;margin-top:4px;flex-wrap:wrap">
|
|
|
|
|
<span>Alokasi waktu<input type="text" name="alokasi_waktu___IDX__" id="rtm_alokasi___IDX__" placeholder="mis. 2 minggu" style="display:block;margin-top:2px;width:200px"></span>
|
|
|
|
|
<span>Tanggal pelaksanaan<input type="text" name="tanggal___IDX__" placeholder="mis. minggu ke-5 s.d. 6" style="display:block;margin-top:2px;width:220px"></span>
|
|
|
|
|
</span>
|
|
|
|
|
</label>
|
|
|
|
|
<label style="display:block;margin-bottom:10px">Lain-lain
|
|
|
|
|
<textarea name="lain_lain___IDX__" rows="2" style="display:block;margin-top:4px;max-width:760px;width:100%"></textarea>
|
|
|
|
|
</label>
|
|
|
|
|
<label style="display:block;margin-bottom:0">Daftar Rujukan
|
|
|
|
|
<textarea name="rujukan___IDX__" rows="2" style="display:block;margin-top:4px;max-width:760px;width:100%"></textarea>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
</details>
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
const RTM_AWAL = {{ rtm_tugas | tojson | safe }};
|
|
|
|
|
let rtmCounter = 0;
|
|
|
|
|
|
|
|
|
|
const BENTUK_TEMPLATE_RTM = {
|
|
|
|
|
Diskusi: {
|
|
|
|
|
deskripsi: 'Diskusikan {SUBCPMK} melalui studi kasus/topik terkait materi ini. Kelompok kecil (3-5 orang) menganalisis permasalahan dan menyusun rekomendasi.',
|
|
|
|
|
metode: '1) Baca materi & bahan diskusi;\n2) Diskusi kelompok;\n3) Susun poin-poin kesimpulan;\n4) Presentasikan hasil diskusi.',
|
|
|
|
|
luaran: 'Notulen/rangkuman diskusi kelompok dalam bentuk dokumen tertulis (maks. 3 halaman).',
|
|
|
|
|
indikator: 'Ketepatan analisis (30%)\nKeaktifan berdiskusi (30%)\nKejelasan kesimpulan (20%)\nKerja sama kelompok (20%)\nBobot: 100%',
|
|
|
|
|
jadwal: '1 minggu',
|
|
|
|
|
},
|
|
|
|
|
PjBL: {
|
|
|
|
|
deskripsi: 'Kerjakan proyek yang menghasilkan solusi nyata terkait {SUBCPMK}, mulai dari perencanaan hingga penyerahan hasil akhir.',
|
|
|
|
|
metode: '1) Identifikasi masalah;\n2) Rencanakan solusi;\n3) Kerjakan proyek secara bertahap;\n4) Uji & perbaiki;\n5) Serahkan hasil akhir beserta laporan.',
|
|
|
|
|
luaran: 'Produk/prototipe beserta laporan tertulis yang menjelaskan proses pengerjaan.',
|
|
|
|
|
indikator: 'Perencanaan (20%)\nProses pengerjaan (30%)\nKualitas hasil akhir (30%)\nLaporan (20%)\nBobot: 100%',
|
|
|
|
|
jadwal: '2-3 minggu',
|
|
|
|
|
},
|
|
|
|
|
CBL: {
|
|
|
|
|
deskripsi: 'Analisis studi kasus terkait {SUBCPMK}; identifikasi permasalahan dan usulkan solusi berbasis konsep yang dipelajari.',
|
|
|
|
|
metode: '1) Baca & pahami kasus;\n2) Identifikasi masalah inti;\n3) Terapkan konsep untuk analisis;\n4) Rumuskan solusi;\n5) Tulis laporan.',
|
|
|
|
|
luaran: 'Laporan analisis kasus tertulis, memuat identifikasi masalah, analisis, dan solusi yang diusulkan.',
|
|
|
|
|
indikator: 'Ketepatan identifikasi masalah (25%)\nKedalaman analisis (35%)\nKetepatan solusi (25%)\nSistematika laporan (15%)\nBobot: 100%',
|
|
|
|
|
jadwal: '1-2 minggu',
|
|
|
|
|
},
|
|
|
|
|
Esai: {
|
|
|
|
|
deskripsi: 'Tulis esai mengenai {SUBCPMK} sepanjang 800-1200 kata, disertai argumen dan referensi yang relevan.',
|
|
|
|
|
metode: '1) Tentukan tesis/argumen utama;\n2) Kumpulkan referensi pendukung;\n3) Susun kerangka esai;\n4) Tulis draf;\n5) Revisi & finalisasi.',
|
|
|
|
|
luaran: 'Esai tertulis (800-1200 kata) dalam format dokumen (PDF/Word).',
|
|
|
|
|
indikator: 'Ketepatan argumen (30%)\nKedalaman analisis (30%)\nSistematika penulisan (20%)\nPenggunaan referensi (20%)\nBobot: 100%',
|
|
|
|
|
jadwal: '1 minggu',
|
|
|
|
|
},
|
|
|
|
|
Tes: {
|
|
|
|
|
deskripsi: 'Kerjakan soal-soal tes tertulis terkait {SUBCPMK} sesuai instruksi yang diberikan.',
|
|
|
|
|
metode: '1) Baca instruksi & soal dengan teliti;\n2) Kerjakan sesuai alokasi waktu;\n3) Periksa kembali jawaban sebelum dikumpulkan.',
|
|
|
|
|
luaran: 'Lembar jawaban tes (tertulis/daring).',
|
|
|
|
|
indikator: 'Ketepatan jawaban per butir soal, dijumlah sesuai bobot masing-masing.\nBobot: 100%',
|
|
|
|
|
jadwal: '1x pertemuan (sesuai jadwal tes)',
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function buatBlokTugasRtm(data) {
|
|
|
|
|
data = data || {};
|
|
|
|
|
const idx = rtmCounter++;
|
|
|
|
|
const html = document.getElementById('tpl-tugas-rtm').innerHTML.split('__IDX__').join(idx);
|
|
|
|
|
const bungkus = document.createElement('div');
|
|
|
|
|
bungkus.innerHTML = html.trim();
|
|
|
|
|
const det = bungkus.firstElementChild;
|
|
|
|
|
det.querySelector(`[name="judul_${idx}"]`).value = data.judul || '';
|
|
|
|
|
(data.subs || []).forEach(kode => {
|
|
|
|
|
const cb = Array.from(det.querySelectorAll(`input[name="subs_${idx}"]`)).find(el => el.value === kode);
|
|
|
|
|
if (cb) cb.checked = true;
|
|
|
|
|
});
|
|
|
|
|
det.querySelector(`#bentuk_tugas_${idx}`).value = data.bentuk_tugas || '';
|
|
|
|
|
det.querySelector(`#tombol_isi_otomatis_${idx}`).hidden = !data.bentuk_tugas;
|
|
|
|
|
det.querySelector(`[name="deskripsi_${idx}"]`).value = data.deskripsi || '';
|
|
|
|
|
det.querySelector(`[name="metode_pengerjaan_${idx}"]`).value = data.metode_pengerjaan || '';
|
|
|
|
|
det.querySelector(`[name="luaran_${idx}"]`).value = data.luaran || '';
|
|
|
|
|
det.querySelector(`[name="indikator_bobot_${idx}"]`).value = data.indikator_bobot || '';
|
|
|
|
|
det.querySelector(`[name="alokasi_waktu_${idx}"]`).value = data.alokasi_waktu || '';
|
|
|
|
|
det.querySelector(`[name="tanggal_${idx}"]`).value = data.tanggal || '';
|
|
|
|
|
det.querySelector(`[name="lain_lain_${idx}"]`).value = data.lain_lain || '';
|
|
|
|
|
det.querySelector(`[name="rujukan_${idx}"]`).value = data.rujukan || '';
|
|
|
|
|
if (data.judul || data.bentuk_tugas) det.open = true;
|
|
|
|
|
document.getElementById('daftar-tugas-rtm').appendChild(det);
|
|
|
|
|
renumberTugasRtm();
|
|
|
|
|
return det;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function tambahTugasRtm() {
|
|
|
|
|
const det = buatBlokTugasRtm();
|
|
|
|
|
det.open = true;
|
|
|
|
|
det.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function hapusTugasRtm(btn) {
|
|
|
|
|
if (!confirm('Hapus blok Tugas ini?')) return;
|
|
|
|
|
btn.closest('details').remove();
|
|
|
|
|
renumberTugasRtm();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renumberTugasRtm() {
|
|
|
|
|
document.querySelectorAll('#daftar-tugas-rtm > details').forEach((det, i) => {
|
|
|
|
|
det.querySelector('.nomor-tugas-rtm').textContent = 'Tugas ' + (i + 1);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function isiOtomatisRtm(idx) {
|
|
|
|
|
const bentuk = document.getElementById('bentuk_tugas_' + idx).value;
|
|
|
|
|
const tmpl = BENTUK_TEMPLATE_RTM[bentuk];
|
|
|
|
|
if (!tmpl) return;
|
|
|
|
|
const checked = Array.from(document.querySelectorAll(`input[name="subs_${idx}"]:checked`)).map(cb => cb.value);
|
|
|
|
|
const subcpmk = checked.length ? checked.join(', ') : 'Sub-CPMK terkait';
|
|
|
|
|
const isi = (id, teks) => {
|
|
|
|
|
const el = document.getElementById(id);
|
|
|
|
|
if (el && !el.value.trim()) el.value = teks.replace('{SUBCPMK}', subcpmk);
|
|
|
|
|
};
|
|
|
|
|
isi('rtm_deskripsi_' + idx, tmpl.deskripsi);
|
|
|
|
|
isi('rtm_metode_' + idx, tmpl.metode);
|
|
|
|
|
isi('rtm_luaran_' + idx, tmpl.luaran);
|
|
|
|
|
isi('rtm_indikator_' + idx, tmpl.indikator);
|
|
|
|
|
isi('rtm_alokasi_' + idx, tmpl.jadwal);
|
|
|
|
|
}
|
|
|
|
|
function toggleIsiOtomatisRtm(idx) {
|
|
|
|
|
const bentuk = document.getElementById('bentuk_tugas_' + idx).value;
|
|
|
|
|
document.getElementById('tombol_isi_otomatis_' + idx).hidden = !bentuk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(RTM_AWAL.length ? RTM_AWAL : [{}]).forEach(buatBlokTugasRtm);
|
|
|
|
|
</script>
|
|
|
|
|
{% endblock %}
|