Appearance
Tiến độ khóa học (Course Progress)
Trang Tiến độ khóa học cho phép trainer xem toàn bộ học viên × toàn bộ hoạt động trong một khóa học của lớp dạng ma trận, đào sâu vào timeline học của từng cặp (học viên, hoạt động), chấm lại điểm bài tập và bài đọc, và ghi chú trực tiếp lên bài cho từng học viên.
Khi nào dùng?
- Theo dõi tổng thể — biết ai chậm, ai nhanh, ai đang ngừng hẳn.
- Trước buổi giảng — kiểm tra ai đã đọc tài liệu / nộp bài chuẩn bị, để bạn tập trung vào phần đa số chưa làm.
- Phản hồi bài tập — đọc submission của học viên, để lại comment hướng dẫn (học viên nhận thông báo).
- Phát hiện anomaly — học viên submit nhưng điểm thấp → xem timeline lý do.
Vào trang
- Mở Trang chi tiết lớp trong Trainer Panel.
- Tab Khóa học — danh sách các khóa thuộc Program của lớp.
- Click một khóa → vào trang Tiến độ khóa học (URL
/trainer/batches/{batch}/course/{course}/progress).
Bố cục ma trận
Header (sticky)
- Cột học viên: tên đầy đủ + email + % tiến độ tổng thể của học viên trong khóa.
- Sticky khi scroll ngang để theo dõi học viên đang xem.
Cột hoạt động
Mỗi cột = một activity (thuộc các module/lesson của khóa). Cột header hiển thị:
- Tên activity
- Loại (Reading / Video / Quiz / Assignment / Code / …)
- Module / lesson chứa activity (gộp visual ở header).
Cell — Trạng thái
| Trạng thái | Hiển thị | Click? |
|---|---|---|
| Chưa bắt đầu | Ô trống | ❌ no-op |
Đang làm (status=started) | Icon đồng hồ vàng + tooltip "Đang làm" | ✅ |
| Đã hoàn thành (có điểm) | Badge điểm điểm / điểm tối đa — xanh nếu đạt, đỏ nếu không. Có icon người kèm theo nếu điểm do giảng viên chấm | ✅ |
| Chờ giảng viên chấm | Badge vàng "Cần chấm" | ✅ |
| Đã hoàn thành (Bài tập có nộp) | Icon ứng với loại nộp: link / văn bản / tệp | ✅ |
| Đã hoàn thành (không chấm) | Dấu tích xanh | ✅ |
Tooltip hover: "Hoàn thành lúc HH:MM dd/mm/yyyy".
Badge "Cần chấm" là gì
AI đã thử chấm nhưng không đọc được bài nộp — link riêng tư, trang chặn đăng nhập, tệp hỏng, hoặc bài nộp trống. Nó không cho điểm trong trường hợp đó, vì một con số đoán ra sẽ đi thẳng vào sổ điểm mà không ai phân biệt được với điểm thật.
Không có badge này thì bài chưa chấm trông y hệt bài đã chấm xong — cả hai đều "hoàn thành", chỉ khác ở chỗ thiếu badge điểm — và cách duy nhất để tìm là bấm thử từng ô. Quét cột tìm màu vàng là cách nhanh nhất để biết hôm nay cần chấm những bài nào.
Badge tắt ngay khi bạn chấm. Nếu vẫn thấy sau khi đã chấm, tải lại trang — bảng cố ý không tự nạp lại (xem FAQ).
Đọc nhanh ma trận
- Cột chủ yếu trống → activity này khó / chưa được thông báo / vô lý → cân nhắc hỗ trợ chung cho lớp.
- Hàng chủ yếu trống → học viên này đã tụt lại → cân nhắc liên hệ + catch-up.
- Badge đỏ trên một cột ở nhiều học viên → đề bài quá khó hoặc đáp án chuẩn có vấn đề → review đề bài.
Drill-down: timeline học chi tiết
Click vào một cell Đang làm hoặc Đã hoàn thành → mở slide-over panel bên phải hiển thị timeline đầy đủ của cặp (học viên × activity).
Header panel
- Tên học viên + tên activity + status badge.
- Thời điểm hoàn thành (nếu có).
Quick stats
3 chỉ số nhanh:
| Chỉ số | Ý nghĩa |
|---|---|
| Số lần thử | Số lần học viên thực sự làm bài. Lượt bạn chấm lại không được tính vào đây |
| Điểm cao nhất | Max (score / max_score) × 100% |
| Thời gian học | Tổng heartbeat_seconds trên activity (đo qua tracking khi học) |
Timeline events
Vertical timeline (cột chấm bên trái + nội dung bên phải), mỗi event là một dòng:
| Event | Khi nào | Nội dung |
|---|---|---|
| Started | Lần đầu mở activity | Thời điểm bắt đầu |
| Attempted #N | Mỗi lần submit (Quiz, Code Practicing, …) | Score badge + AI feedback (nếu có) + criteria đã đạt/chưa |
| Submitted | Assignment / Reading có summary | Nội dung text/HTML đã sanitize, kèm link / file download nếu có |
| Completed | Activity được đánh dấu hoàn thành | Thời điểm + nguồn (auto / manual) |
| Đã chấm lại | Giảng viên đặt điểm cho bài | Tên người chấm + điểm + nhận xét gửi học viên |
| Commented | Trainer thêm ghi chú | Tên người, thời gian, nội dung đã render |
Dữ liệu được build qua ActivityProgressTimelineService từ Progress + ActivityAttempt + ActivityProgressComment, sort theo thời gian tăng dần.
Đọc nội dung submission an toàn
Hệ thống sanitize HTML (qua Symfony\HtmlSanitizer) cho mọi text/HTML nhập từ học viên — strip <script>, các thuộc tính on*, JS schemes. Bạn có thể đọc bài nộp mà không lo XSS.
Chấm lại điểm
Cuối slide-over, dưới timeline, có khối Chấm lại điểm — hiện với Bài tập và Bài đọc có tóm tắt khi bạn là giảng viên của lớp.
- Ô Điểm điền sẵn điểm đang hiệu lực (điểm bạn đã chấm nếu có, không thì điểm AI). Ô rỗng nghĩa là chưa ai chấm.
- Nhận xét cho học viên — học viên sẽ đọc câu này. Viết lý do, đừng chỉ đổi số.
- Lưu điểm — điểm của bạn thay thế điểm AI trên màn hình học viên, kèm nhãn "Điểm do giảng viên chấm".
Chi tiết đầy đủ (điều gì xảy ra với trạng thái hoàn thành, học viên nộp lại, ai được chấm): Chấm điểm & Feedback.
Ghi chú trainer
Để lại comment
Cuối panel timeline có form Thêm ghi chú:
- Click vào ô editor → Tiptap rich editor mở (toolbar B/I/U/S, H1-H3, list, blockquote, link).
- Viết nội dung — có thể format đầy đủ + chèn link.
- Click Gửi ghi chú → comment được thêm vào timeline ngay, editor reset.
HTML sanitize
Comment được sanitize 2 lần (khi lưu + khi đọc) → defense-in-depth. Comment trống / chỉ khoảng trắng bị bỏ qua.
Ghi chú hiển thị ở đâu?
- Trong timeline — cho bạn và các trainer khác cùng lớp, cùng Tenant Admin.
- Chuông thông báo của học viên — học viên nhận thông báo trong app ngay khi bạn gửi.
Ghi chú không phải là nhận xét chấm bài
Học viên nhận thông báo về ghi chú, nhưng ghi chú không hiện cạnh điểm trên trang học của họ. Muốn viết một câu học viên chắc chắn đọc cùng lúc với điểm, hãy dùng ô Nhận xét cho học viên trong khối Chấm lại điểm — câu đó hiện ngay dưới con số.
Xóa comment
Mỗi comment có icon 🗑 (heroicon trash) bên cạnh:
- Tác giả luôn xóa được comment của mình.
- Trainer khác (có quyền
update batch) cũng có thể xóa — phòng trường hợp đồng nghiệp xóa giúp khi tác giả vắng. super_adminxóa được mọi comment.
Ghi chú không thay đổi điểm
Ghi chú là note bổ sung. Hệ thống chấm tự động (Quiz, Code Practicing) không bị ảnh hưởng.
Để thay đổi điểm thì dùng khối Chấm lại điểm ở trên — chi tiết ở Chấm điểm & Feedback.
Trường hợp dùng phổ biến
1. Phản hồi bài tập (Assignment)
Học viên nộp bài tập viết / code → bạn click vào cell tương ứng → đọc submission trong panel → comment góp ý cụ thể.
"@Bạn đã viết phần phân tích thuật toán rất tốt. Phần code có thể tối ưu thêm bằng cách dùng dictionary thay list — thử xem
helpers.pymình gửi tuần trước."
2. Hướng dẫn debug code
Học viên submit Code Practicing fail nhiều lần → mở timeline → đọc các attempt thất bại → comment hint:
"Mình thấy bạn đang fail test #3. Hint: thử với input
n=0xem hàm có chia cho 0 không."
3. Khen ngợi / khích lệ
Học viên hoàn thành tốt bài khó:
"Solution của bạn rất sạch! Cách dùng generator giảm hẳn memory. Đáng học hỏi 👏"
(học viên nhận thông báo + thấy comment + tăng động lực)
4. Theo dõi học viên đang chững
Học viên ngừng làm bài 1 tuần → bạn vào ma trận thấy hàng nhiều ô trống → click vào ô Đang làm gần nhất → comment hỏi thăm + nhắc nhở:
"@Bạn đang dừng ở đây bao lâu rồi nhỉ? Có gì khó không, mình hỗ trợ?"
Mối liên hệ với các trang khác
| Tình huống | Trang phù hợp |
|---|---|
| Cần nhìn tổng thể nhiều khóa trong lớp | Tab Học viên trong trang chi tiết lớp |
| Cần xem tổng thể năng lực thay vì hoạt động | Bản đồ năng lực |
| Cần giảm tải học viên đang chậm | Kế hoạch bắt kịp |
| Cần ẩn / bắt buộc hoạt động cho 1 học viên | Tùy chỉnh hoạt động |
Câu hỏi thường gặp
Trang ma trận tải chậm khi lớp đông + khóa dài? Hệ thống query 1 lần cho toàn bộ Enrollment + Progress + ActivityAttempt của khóa, render bảng client-side. Với lớp ~50 học viên × ~100 activity vẫn ổn (5000 cell). Lớp lớn hơn (>100 học viên) có thể cần Tenant Admin tối ưu.
Tôi không thấy điểm trên cell mặc dù học viên đã làm Quiz? Cần ActivityAttempt.max_score > 0. Quiz mặc định có max_score. Nếu vẫn không hiện, có thể quiz được cấu hình "không chấm" — chỉ hiện dấu tích xanh.
Học viên bảo không thấy ghi chú của tôi? Ghi chú tới học viên bằng thông báo trong app (chuông), không hiện cạnh nội dung bài học. Nếu chuông không lên số, kiểm tra ghi chú có nội dung thật (không chỉ khoảng trắng). Cần một câu học viên chắc chắn đọc cùng với điểm thì viết vào ô Nhận xét cho học viên khi chấm.
Học viên trả lời ghi chú của tôi như thế nào? Chưa có đường trả lời ngay trên hoạt động. Học viên phản hồi qua các kênh sẵn có (bảng tin khoá học, buổi học trực tiếp, yêu cầu học viên).
Có thể @mention trong comment activity không? Hiện tại comment activity chưa có @mention (chỉ batch log có). Nếu cần ping ai đó, viết tên rõ ràng + dùng nhật ký lớp song song.
Comment có xóa được sau khi học viên đã đọc? Có — không bị khóa 24h như batch log. Tuy vậy, học viên có thể đã đọc snapshot trước đó. Hệ thống không lưu phiên bản cũ.
Tôi muốn nhận thông báo khi học viên reply comment của tôi? Lộ trình sắp tới — bell event đã có khung từ phía tổ chức, chưa kích hoạt cho trainer.
Comment có hiện trên Tenant Admin Panel không? Có — cùng một timeline được render cả ở Tenant Admin (BatchCourseProgress page). Đồng nghiệp / admin xem được.
Có rate limit không khi tôi spam comment? Không có rate limit cứng. Tuy vậy, hãy giữ nội dung có giá trị — học viên nhận notification mỗi comment, bị spam có thể gây phản ứng ngược.
Bài tập của học viên có nhiều tệp đính kèm — tôi xem được hết? Mỗi lần nộp mang một tệp (hoặc một link, một đoạn văn bản, hoặc một bản ghi âm — hình thức nộp do người soạn khoá chọn, chỉ một). Timeline hiển thị đúng thứ đó: nút tải tệp, link, nội dung văn bản, hoặc trình phát bản ghi kèm nút tải.
Tôi vừa chấm xong mà ô trên bảng vẫn hiện điểm cũ / badge "Cần chấm"? Bảng ma trận cố ý không tự nạp lại: nó phải gửi lại toàn bộ lưới học viên × hoạt động, rất nặng với lớp đông — đó cũng là lý do slide-over là một thành phần tách riêng. Tải lại trang là xong. Slide-over đã hiện điểm mới ngay khi bạn lưu.