Rapikan tampilan nilai, ganti NPM->NIM, fitur ganti password, kunci RPS view-only
- Tampilan "Isi Per Komponen Penilaian" diganti dari tombol bertumpuk teks jadi tabel (Komponen/Sub-CPMK/Bobot/Status/Aksi) dengan status berupa stempel, lebih mudah dipindai. - Filter pencarian MK (ketik kode/nama) di kotak penugasan dosen /admin. - Istilah NPM diseragamkan jadi NIM di seluruh aplikasi (label, header, template Excel, dokumen portofolio), termasuk migrasi kolom database mahasiswa.npm -> nim yang aman (ALTER TABLE RENAME COLUMN, otomatis saat startup, tanpa kehilangan data; parser Excel tetap terima file lama berheader NPM). - Fitur ganti password mandiri (/akun): verifikasi password lama, sesi lain otomatis keluar setelah berhasil, sesi yang dipakai tetap aktif. - RPS: dosen RPS+MK kini bisa menyesuaikan redaksi kalimat Sub-CPMK (bagian D) untuk MK yang diampu -- kode & kaitan CPMK/CPL tetap dari kurikulum, hanya teksnya yang bisa disesuaikan. Penyesuaian otomatis konsisten di dropdown mingguan (F), checklist komponen (G), serta unduhan RPS & portofolio, tanpa menyentuh data kurikulum induk atau halaman nilai/ dashboard prodi. - Form RPS dibungkus <fieldset disabled> untuk dosen tanpa hak edit -- seluruh field benar-benar terkunci (bukan cuma tombol simpan hilang).
This commit is contained in:
@@ -39,13 +39,18 @@
|
||||
<details style="margin-top:6px">
|
||||
<summary style="cursor:pointer;color:var(--blue);font-size:13px">Ubah penugasan…</summary>
|
||||
<form method="post" action="/admin/pengguna/{{ p.id }}/tugas">
|
||||
<div class="pilih-sub" style="max-height:220px;margin:6px 0">
|
||||
<input type="text" class="cari-mk" placeholder="Cari kode/nama MK…"
|
||||
style="width:260px;margin:6px 0 4px;font-size:13px">
|
||||
<div class="pilih-sub" style="max-height:220px;margin:0 0 6px">
|
||||
{% for mk in daftar %}
|
||||
<label><input type="checkbox" name="mk" value="{{ mk.kode }}"
|
||||
{% if mk.kode in p.mk %}checked{% endif %}> {{ mk.kode }} — {{ mk.nama }}</label>
|
||||
<input type="text" name="kelas_{{ mk.kode }}" placeholder="kelas (kosong = semua)"
|
||||
value="{{ p.kelas_map.get(mk.kode, '') }}" style="width:150px;margin:0 0 4px 22px;font-size:12px">
|
||||
<div class="baris-mk" data-cari="{{ (mk.kode ~ ' ' ~ mk.nama)|lower }}">
|
||||
<label><input type="checkbox" name="mk" value="{{ mk.kode }}"
|
||||
{% if mk.kode in p.mk %}checked{% endif %}> {{ mk.kode }} — {{ mk.nama }}</label>
|
||||
<input type="text" name="kelas_{{ mk.kode }}" placeholder="kelas (kosong = semua)"
|
||||
value="{{ p.kelas_map.get(mk.kode, '') }}" style="width:150px;margin:0 0 4px 22px;font-size:12px">
|
||||
</div>
|
||||
{% endfor %}
|
||||
<p class="cari-kosong" style="display:none;color:var(--grey);font-size:13px;margin:4px 0">Tidak ada MK yang cocok.</p>
|
||||
</div>
|
||||
<button class="tombol garis" type="submit" style="padding:4px 12px;font-size:13px">Simpan Penugasan</button>
|
||||
</form>
|
||||
@@ -91,7 +96,7 @@
|
||||
|
||||
<h2 class="bagian">C. Daftar Mahasiswa Mengontrak MK — {{ tahun }}</h2>
|
||||
<p class="keterangan">Unggah satu file Excel berisi seluruh kontrak semester ini
|
||||
(kolom: NPM, Nama, Kode MK, Kelas — satu baris per kontrak). Impor baru
|
||||
(kolom: NIM, Nama, Kode MK, Kelas — satu baris per kontrak). Impor baru
|
||||
<b>menggantikan seluruh daftar</b> tahun ajaran aktif. Daftar ini dipakai untuk
|
||||
mengisi otomatis template nilai tiap MK.</p>
|
||||
<div class="aksi-baris" style="border-top:none;padding-top:0;margin-top:8px">
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
</span>
|
||||
<span class="menu-kanan">
|
||||
<b>{{ user.nama }}</b> — {{ {'kaprodi': 'Kaprodi', 'dosen_rps_mk': 'Dosen RPS + MK', 'dosen_mk': 'Dosen MK'}[user.role] }}
|
||||
· <a href="/akun">Ganti Password</a>
|
||||
· <a href="/keluar">Keluar</a>
|
||||
</span>
|
||||
</nav>
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:44px" class="tengah">No.</th>
|
||||
<th style="width:112px">NPM</th>
|
||||
<th style="width:112px">NIM</th>
|
||||
<th style="min-width:150px">Nama</th>
|
||||
{% if ada_kelas %}<th style="width:60px" class="tengah">Kelas</th>{% endif %}
|
||||
{% for s in peta.subs %}<th class="tengah" style="font-size:11px;min-width:62px">{{ s.kode }}</th>{% endfor %}
|
||||
@@ -104,9 +104,9 @@
|
||||
{% set i = loop.index0 %}
|
||||
<tr>
|
||||
<td class="tengah">{{ loop.index }}
|
||||
<input type="hidden" name="npm_{{ i }}" value="{{ m.npm }}">
|
||||
<input type="hidden" name="nim_{{ i }}" value="{{ m.nim }}">
|
||||
<input type="hidden" name="nama_{{ i }}" value="{{ m.nama }}"></td>
|
||||
<td>{{ m.npm }}</td>
|
||||
<td>{{ m.nim }}</td>
|
||||
<td>{{ m.nama }}</td>
|
||||
{% if ada_kelas %}<td class="tengah">{{ m.kelas or '—' }}</td>{% endif %}
|
||||
{% for s in peta.subs %}
|
||||
@@ -114,7 +114,7 @@
|
||||
min="0" max="100" step="0.01"
|
||||
value="{{ '%g'|format(m.skor[s.kode]) if s.kode in m.skor else '' }}"></td>
|
||||
{% endfor %}
|
||||
<td class="tengah"><b>{{ '%.1f'|format(akhir.get(m.npm)) if akhir.get(m.npm) is not none else '—' }}</b></td>
|
||||
<td class="tengah"><b>{{ '%.1f'|format(akhir.get(m.nim)) if akhir.get(m.nim) is not none else '—' }}</b></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
{% if per_mhs and hasil %}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:44px" class="tengah">No.</th>
|
||||
<th style="width:112px">NPM</th>
|
||||
<th style="width:112px">NIM</th>
|
||||
<th style="min-width:150px">Nama</th>
|
||||
<th class="tengah" style="width:140px">Nilai (0–100)</th>
|
||||
</tr>
|
||||
@@ -66,9 +66,9 @@
|
||||
{% for m in grid %}
|
||||
<tr>
|
||||
<td class="tengah">{{ loop.index }}
|
||||
<input type="hidden" name="npm_{{ loop.index0 }}" value="{{ m.npm }}">
|
||||
<input type="hidden" name="nim_{{ loop.index0 }}" value="{{ m.nim }}">
|
||||
<input type="hidden" name="nama_{{ loop.index0 }}" value="{{ m.nama }}"></td>
|
||||
<td>{{ m.npm }}</td>
|
||||
<td>{{ m.nim }}</td>
|
||||
<td>{{ m.nama }}</td>
|
||||
<td class="isian"><input type="number" name="nilai_{{ loop.index0 }}"
|
||||
min="0" max="100" step="0.01"
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="/rps/{{ peta.kode }}">
|
||||
<fieldset {% if not boleh_edit %}disabled{% endif %} style="border:none;padding:0;margin:0">
|
||||
|
||||
<h2 class="bagian">A. IDENTITAS MATA KULIAH</h2>
|
||||
<table class="grid">
|
||||
@@ -77,13 +78,15 @@
|
||||
</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>
|
||||
<h2 class="bagian">D. SUB-CPMK <span style="font-weight:normal;font-style:italic;color:var(--grey)">— kode & kaitan CPMK otomatis dari pemetaan kurikulum ({{ peta.subs|length }} butir); redaksi kalimat boleh disesuaikan bila perlu</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>
|
||||
<tr><td class="tengah">{{ s.kode }}</td>
|
||||
<td class="isian"><textarea name="sub_uraian_{{ s.kode }}" rows="2">{{ s.uraian }}</textarea></td>
|
||||
<td class="tengah">{{ s.cpmk }}</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -206,6 +209,7 @@
|
||||
<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>
|
||||
|
||||
</fieldset>
|
||||
<div class="aksi-baris">
|
||||
{% if boleh_edit %}
|
||||
<span style="color:var(--grey);font-size:13px">Disimpan atas nama <b>{{ user.nama }}</b></span>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
{% extends "base.html" %}
|
||||
{% block judul %}Ganti Password — RPS & Portofolio UNTAN{% endblock %}
|
||||
{% block isi %}
|
||||
<h1>Ganti Password</h1>
|
||||
<p class="keterangan">Berlaku untuk akun Anda sendiri (<b>{{ user.nama }}</b>).
|
||||
Setelah berhasil, sesi login lain dari akun ini akan keluar otomatis dan
|
||||
Anda perlu memakai password baru pada login berikutnya.</p>
|
||||
|
||||
{% if pesan %}<div class="info">{{ pesan }}</div>{% endif %}
|
||||
{% if error %}<div class="peringatan">{{ error }}</div>{% endif %}
|
||||
|
||||
<div style="max-width:360px">
|
||||
<form method="post" action="/akun">
|
||||
<label for="lama" style="display:block;font-size:14px;margin:12px 0 3px">Password lama</label>
|
||||
<input type="password" id="lama" name="lama" autocomplete="current-password" required autofocus>
|
||||
<label for="baru" style="display:block;font-size:14px;margin:12px 0 3px">Password baru <span style="color:var(--grey);font-weight:normal">(minimal 4 karakter)</span></label>
|
||||
<input type="password" id="baru" name="baru" autocomplete="new-password" minlength="4" required>
|
||||
<label for="ulang" style="display:block;font-size:14px;margin:12px 0 3px">Ulangi password baru</label>
|
||||
<input type="password" id="ulang" name="ulang" autocomplete="new-password" minlength="4" required>
|
||||
<div class="aksi-baris" style="border-top:none;padding-top:10px">
|
||||
<button class="tombol" type="submit">Simpan Password Baru</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user