feat(course): reset student course progress (#671)
* feat(course): add reset student course progress action Give course admins and tutors a destructive reset-progress flow on the student people detail page. The backend clears learner progress for one (courseId, memberId) pair in a single transaction while keeping the groupmember enrolled, and logs an audit summary. The dashboard shows a confirmation dialog with impact counts from analytics before deleting. Co-authored-by: Rotimi Best <[email protected]> * fix(i18n): add localized reset progress strings for all locales Co-authored-by: Rotimi Best <[email protected]> * fix(course): scope reset progress to course data only Stop deleting org-level community questions and answers during course progress reset. Fix course newsfeed deletion order so comments on a student's posts are removed before the posts themselves. Restrict reset to student members, move analytics loading to the person detail layout, and rename impact copy to course newsfeed only. Co-authored-by: Rotimi Best <[email protected]> * fix(course): address Greptile review on reset progress Make progressImpact opt-in via includeProgressImpact query param so analytics requests avoid extra DB work unless the reset dialog needs it. Count only student-authored course newsfeed posts and comments in the impact summary to avoid double-counting replies on the student's posts. Co-authored-by: Rotimi Best <[email protected]> --------- Co-authored-by: Cursor Agent <[email protected]> Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
Cursor Agent
parent
e43d8a2444
commit
a695c97eda
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Frigjort",
|
||||
"successfully": "Med succes",
|
||||
"feed_delete_success": "Feedet blev slettet"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Fremskridt nulstillet",
|
||||
"progress_reset_failed": "Kunne ikke nulstille fremskridt"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "Nej",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Nulstil fremskridt",
|
||||
"dialog": {
|
||||
"title": "Nulstil fremskridt for {studentName}?",
|
||||
"intro": "Dette sletter permanent denne elevs fremskridt i dette kursus. Eleven forbliver tilmeldt og kan starte forfra fra lektion 1.",
|
||||
"bullets": {
|
||||
"lessons": "Gennemførte lektioner — {completed} af {total}",
|
||||
"exercises": "Afleverede øvelser — {count} afleveringer",
|
||||
"comments": "Lektionskommentarer fra denne elev — {count}",
|
||||
"newsfeed": "Kursusnyhedsfeed-opslag og svar fra denne elev — {count}",
|
||||
"video_progress": "Videofremskridt — {count} lektioner sporet",
|
||||
"attendance": "Fremmødeposter — {count}",
|
||||
"certificate_yes": "Certificerings-/compliance-data — ja",
|
||||
"certificate_no": "Certificerings-/compliance-data — nej"
|
||||
},
|
||||
"warning": "Dette kan ikke fortrydes.",
|
||||
"cancel": "Annuller",
|
||||
"confirm": "Slet"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "Inviter folk",
|
||||
"invite": "Inviter undervisere",
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Nicht angepinnt",
|
||||
"successfully": "Erfolgreich",
|
||||
"feed_delete_success": "Feed erfolgreich gelöscht"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Fortschritt zurückgesetzt",
|
||||
"progress_reset_failed": "Fortschritt konnte nicht zurückgesetzt werden"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "Nein",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Fortschritt zurücksetzen",
|
||||
"dialog": {
|
||||
"title": "Fortschritt von {studentName} zurücksetzen?",
|
||||
"intro": "Dadurch wird der Fortschritt dieses Teilnehmers in diesem Kurs dauerhaft gelöscht. Die Person bleibt eingeschrieben und kann bei Lektion 1 neu beginnen.",
|
||||
"bullets": {
|
||||
"lessons": "Abgeschlossene Lektionen — {completed} von {total}",
|
||||
"exercises": "Eingereichte Übungen — {count} Abgaben",
|
||||
"comments": "Lektionskommentare dieses Teilnehmers — {count}",
|
||||
"newsfeed": "Kurs-Newsfeed-Beiträge und Antworten dieses Teilnehmers — {count}",
|
||||
"video_progress": "Videofortschritt — {count} verfolgte Lektionen",
|
||||
"attendance": "Anwesenheitseinträge — {count}",
|
||||
"certificate_yes": "Zertifizierungs-/Compliance-Daten — ja",
|
||||
"certificate_no": "Zertifizierungs-/Compliance-Daten — nein"
|
||||
},
|
||||
"warning": "Dies kann nicht rückgängig gemacht werden.",
|
||||
"cancel": "Abbrechen",
|
||||
"confirm": "Löschen"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "Leute einladen",
|
||||
"invite": "Laden Sie Tutoren ein",
|
||||
|
||||
@@ -3308,6 +3308,26 @@
|
||||
"no": "No",
|
||||
"yes": "Yes"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Reset progress",
|
||||
"dialog": {
|
||||
"title": "Reset progress for {studentName}?",
|
||||
"intro": "This permanently deletes this student's progress in this course. They will stay enrolled and can restart from lesson 1.",
|
||||
"bullets": {
|
||||
"lessons": "Lessons completed — {completed} of {total}",
|
||||
"exercises": "Exercises submitted — {count} submissions",
|
||||
"comments": "Lesson comments by this student — {count}",
|
||||
"newsfeed": "Course newsfeed posts and replies by this student — {count}",
|
||||
"video_progress": "Video watch progress — {count} lessons tracked",
|
||||
"attendance": "Attendance entries — {count}",
|
||||
"certificate_yes": "Certification / compliance records — yes",
|
||||
"certificate_no": "Certification / compliance records — no"
|
||||
},
|
||||
"warning": "This cannot be undone.",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Delete"
|
||||
}
|
||||
},
|
||||
"roles": {
|
||||
"admin": "Admin",
|
||||
"tutor": "Tutor",
|
||||
@@ -4196,6 +4216,10 @@
|
||||
"toggle_error": "Failed to toggle pinned feed",
|
||||
"news_feed_fail": "Failed to fetch news feeds",
|
||||
"feed_fetch_error": "An error occured while fetching feed"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Progress reset",
|
||||
"progress_reset_failed": "Failed to reset progress"
|
||||
}
|
||||
},
|
||||
"lms": {
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Desanclar",
|
||||
"successfully": "Con éxito",
|
||||
"feed_delete_success": "Feed eliminado correctamente"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Progreso restablecido",
|
||||
"progress_reset_failed": "No se pudo restablecer el progreso"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "No",
|
||||
"yes": "si"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Restablecer progreso",
|
||||
"dialog": {
|
||||
"title": "¿Restablecer el progreso de {studentName}?",
|
||||
"intro": "Esto elimina permanentemente el progreso de este estudiante en este curso. Seguirá inscrito y podrá empezar de nuevo desde la lección 1.",
|
||||
"bullets": {
|
||||
"lessons": "Lecciones completadas — {completed} de {total}",
|
||||
"exercises": "Ejercicios enviados — {count} entregas",
|
||||
"comments": "Comentarios de lección de este estudiante — {count}",
|
||||
"newsfeed": "Publicaciones y respuestas del feed del curso de este estudiante — {count}",
|
||||
"video_progress": "Progreso de visualización de video — {count} lecciones registradas",
|
||||
"attendance": "Registros de asistencia — {count}",
|
||||
"certificate_yes": "Registros de certificación/cumplimiento — sí",
|
||||
"certificate_no": "Registros de certificación/cumplimiento — no"
|
||||
},
|
||||
"warning": "Esto no se puede deshacer.",
|
||||
"cancel": "Cancelar",
|
||||
"confirm": "Eliminar"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "invitar gente",
|
||||
"invite": "Invitar tutores",
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Désépinglé",
|
||||
"successfully": "Avec succès",
|
||||
"feed_delete_success": "Flux supprimé avec succès"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Progression réinitialisée",
|
||||
"progress_reset_failed": "Échec de la réinitialisation de la progression"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "Non",
|
||||
"yes": "Oui"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Réinitialiser la progression",
|
||||
"dialog": {
|
||||
"title": "Réinitialiser la progression de {studentName} ?",
|
||||
"intro": "Cela supprime définitivement la progression de cet apprenant dans ce cours. Il restera inscrit et pourra recommencer à la leçon 1.",
|
||||
"bullets": {
|
||||
"lessons": "Leçons terminées — {completed} sur {total}",
|
||||
"exercises": "Exercices soumis — {count} soumissions",
|
||||
"comments": "Commentaires de leçon de cet apprenant — {count}",
|
||||
"newsfeed": "Publications et réponses du fil d’actualité du cours de cet apprenant — {count}",
|
||||
"video_progress": "Progression de visionnage vidéo — {count} leçons suivies",
|
||||
"attendance": "Entrées de présence — {count}",
|
||||
"certificate_yes": "Dossiers de certification/conformité — oui",
|
||||
"certificate_no": "Dossiers de certification/conformité — non"
|
||||
},
|
||||
"warning": "Cette action est irréversible.",
|
||||
"cancel": "Annuler",
|
||||
"confirm": "Supprimer"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "Inviter des personnes",
|
||||
"invite": "Inviter des tuteurs",
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "अनपिन किया गया",
|
||||
"successfully": "सफलतापूर्वक",
|
||||
"feed_delete_success": "फ़ीड सफलतापूर्वक हटा दी गई"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "प्रगति रीसेट की गई",
|
||||
"progress_reset_failed": "प्रगति रीसेट नहीं हो सकी"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "नहीं",
|
||||
"yes": "हाँ"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "प्रगति रीसेट करें",
|
||||
"dialog": {
|
||||
"title": "{studentName} की प्रगति रीसेट करें?",
|
||||
"intro": "यह इस कोर्स में इस छात्र की प्रगति को स्थायी रूप से हटा देगा। वे नामांकित रहेंगे और पाठ 1 से फिर से शुरू कर सकेंगे।",
|
||||
"bullets": {
|
||||
"lessons": "पूर्ण पाठ — {completed} में से {total}",
|
||||
"exercises": "जमा किए गए अभ्यास — {count} सबमिशन",
|
||||
"comments": "इस छात्र के पाठ टिप्पणियाँ — {count}",
|
||||
"newsfeed": "इस छात्र की कोर्स न्यूज़फ़ीड पोस्ट और जवाब — {count}",
|
||||
"video_progress": "वीडियो देखने की प्रगति — {count} ट्रैक किए गए पाठ",
|
||||
"attendance": "उपस्थिति प्रविष्टियाँ — {count}",
|
||||
"certificate_yes": "प्रमाणन/अनुपालन रिकॉर्ड — हाँ",
|
||||
"certificate_no": "प्रमाणन/अनुपालन रिकॉर्ड — नहीं"
|
||||
},
|
||||
"warning": "इसे पूर्ववत नहीं किया जा सकता।",
|
||||
"cancel": "रद्द करें",
|
||||
"confirm": "हटाएँ"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "लोगों को आमंत्रित करें",
|
||||
"invite": "शिक्षकों को आमंत्रित करें",
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Odpięty",
|
||||
"successfully": "Pomyślnie",
|
||||
"feed_delete_success": "Kanał został pomyślnie usunięty"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Postęp został zresetowany",
|
||||
"progress_reset_failed": "Nie udało się zresetować postępu"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "Nie",
|
||||
"yes": "Tak"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Zresetuj postęp",
|
||||
"dialog": {
|
||||
"title": "Zresetować postęp użytkownika {studentName}?",
|
||||
"intro": "Spowoduje to trwałe usunięcie postępu tego uczestnika w tym kursie. Pozostanie zapisany i będzie mógł zacząć od lekcji 1.",
|
||||
"bullets": {
|
||||
"lessons": "Ukończone lekcje — {completed} z {total}",
|
||||
"exercises": "Przesłane ćwiczenia — {count} zgłoszeń",
|
||||
"comments": "Komentarze do lekcji tego uczestnika — {count}",
|
||||
"newsfeed": "Wpisy i odpowiedzi na kanale kursu tego uczestnika — {count}",
|
||||
"video_progress": "Postęp oglądania wideo — {count} śledzonych lekcji",
|
||||
"attendance": "Wpisy obecności — {count}",
|
||||
"certificate_yes": "Rekordy certyfikacji/zgodności — tak",
|
||||
"certificate_no": "Rekordy certyfikacji/zgodności — nie"
|
||||
},
|
||||
"warning": "Tej operacji nie można cofnąć.",
|
||||
"cancel": "Anuluj",
|
||||
"confirm": "Usuń"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "Zaproś ludzi",
|
||||
"invite": "Zaproś korepetytorów",
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Desafixado",
|
||||
"successfully": "Com sucesso",
|
||||
"feed_delete_success": "Feed excluído com sucesso"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Progresso redefinido",
|
||||
"progress_reset_failed": "Falha ao redefinir o progresso"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "Não",
|
||||
"yes": "Sim"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Redefinir progresso",
|
||||
"dialog": {
|
||||
"title": "Redefinir o progresso de {studentName}?",
|
||||
"intro": "Isso exclui permanentemente o progresso deste aluno neste curso. Ele permanecerá matriculado e poderá recomeçar da lição 1.",
|
||||
"bullets": {
|
||||
"lessons": "Lições concluídas — {completed} de {total}",
|
||||
"exercises": "Exercícios enviados — {count} envios",
|
||||
"comments": "Comentários de lição deste aluno — {count}",
|
||||
"newsfeed": "Publicações e respostas no feed do curso deste aluno — {count}",
|
||||
"video_progress": "Progresso de visualização de vídeo — {count} lições acompanhadas",
|
||||
"attendance": "Registros de presença — {count}",
|
||||
"certificate_yes": "Registros de certificação/conformidade — sim",
|
||||
"certificate_no": "Registros de certificação/conformidade — não"
|
||||
},
|
||||
"warning": "Isso não pode ser desfeito.",
|
||||
"cancel": "Cancelar",
|
||||
"confirm": "Excluir"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "Convide pessoas",
|
||||
"invite": "Convidar tutores",
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Откреплено",
|
||||
"successfully": "Успешно",
|
||||
"feed_delete_success": "Фид успешно удален"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Прогресс сброшен",
|
||||
"progress_reset_failed": "Не удалось сбросить прогресс"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "Нет",
|
||||
"yes": "Да"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Сбросить прогресс",
|
||||
"dialog": {
|
||||
"title": "Сбросить прогресс для {studentName}?",
|
||||
"intro": "Это навсегда удалит прогресс этого студента в данном курсе. Он останется зачисленным и сможет начать заново с урока 1.",
|
||||
"bullets": {
|
||||
"lessons": "Завершённые уроки — {completed} из {total}",
|
||||
"exercises": "Отправленные упражнения — {count} отправок",
|
||||
"comments": "Комментарии к урокам этого студента — {count}",
|
||||
"newsfeed": "Посты и ответы в ленте курса от этого студента — {count}",
|
||||
"video_progress": "Прогресс просмотра видео — {count} отслеживаемых уроков",
|
||||
"attendance": "Записи посещаемости — {count}",
|
||||
"certificate_yes": "Записи сертификации/соответствия — да",
|
||||
"certificate_no": "Записи сертификации/соответствия — нет"
|
||||
},
|
||||
"warning": "Это действие нельзя отменить.",
|
||||
"cancel": "Отмена",
|
||||
"confirm": "Удалить"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "Пригласить людей",
|
||||
"invite": "Пригласить репетиторов",
|
||||
|
||||
@@ -242,6 +242,10 @@
|
||||
"unpinned": "Đã bỏ ghim",
|
||||
"successfully": "thành công",
|
||||
"feed_delete_success": "Đã xóa nguồn cấp dữ liệu thành công"
|
||||
},
|
||||
"people": {
|
||||
"progress_reset": "Đã đặt lại tiến độ",
|
||||
"progress_reset_failed": "Không thể đặt lại tiến độ"
|
||||
}
|
||||
},
|
||||
"landing_page_settings": {
|
||||
@@ -1100,6 +1104,26 @@
|
||||
"no": "Không",
|
||||
"yes": "Có"
|
||||
},
|
||||
"reset_progress": {
|
||||
"button": "Đặt lại tiến độ",
|
||||
"dialog": {
|
||||
"title": "Đặt lại tiến độ cho {studentName}?",
|
||||
"intro": "Thao tác này xóa vĩnh viễn tiến độ của học viên này trong khóa học. Họ vẫn được ghi danh và có thể bắt đầu lại từ bài 1.",
|
||||
"bullets": {
|
||||
"lessons": "Bài học đã hoàn thành — {completed}/{total}",
|
||||
"exercises": "Bài tập đã nộp — {count} bài nộp",
|
||||
"comments": "Bình luận bài học của học viên này — {count}",
|
||||
"newsfeed": "Bài đăng và phản hồi bảng tin khóa học của học viên này — {count}",
|
||||
"video_progress": "Tiến độ xem video — {count} bài học được theo dõi",
|
||||
"attendance": "Mục điểm danh — {count}",
|
||||
"certificate_yes": "Hồ sơ chứng nhận/tuân thủ — có",
|
||||
"certificate_no": "Hồ sơ chứng nhận/tuân thủ — không"
|
||||
},
|
||||
"warning": "Không thể hoàn tác.",
|
||||
"cancel": "Hủy",
|
||||
"confirm": "Xóa"
|
||||
}
|
||||
},
|
||||
"invite_modal": {
|
||||
"title": "Mời mọi người",
|
||||
"invite": "Mời gia sư",
|
||||
|
||||
Reference in New Issue
Block a user