diff --git a/CHANGELOG.md b/CHANGELOG.md
index 673c792dfb661892670d1ffe653d1b34d3d20f6b..3f4835063a5ae76a6043b115cf5ee934e087b2d5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -65,6 +65,10 @@ Context manquant.
## Améliorations
+### Général
+
+[ ] Vérifier que l'activation des compétences dans le site, et la présence de compétences dans le cours est bien vérifiée partout et que des messages d'information clairs sont affichés dans ce cas.
+
### JS
Suppressions de `console.log()` multiples.
@@ -91,25 +95,35 @@ Ne pas utiliser de méthodes root, quitte à abandonner des fonctionnalités. Tr
[x] Pouvoir changer d'utilisateur via des boutons précédent, suivant
-[0] Permettre de filtrer par proficiency et par grade => pas la peine, c'est lisible et on voir bien avec les couleurs.
+[ ] Traiter le cas où il n'y a pas de compétences dans le cours (renvoyer vers la matrice)
[ ] Générer un lien vers la page cpt x users
- (quelques éléments dans le lien)
+[ ] Afficher la progression de l'utilisateur dans la page ? count_proficient_competencies_in_course_for_user
+
### Page statut des utilisateurs pour une compétence
-[ ] Lister l'état d'acquisitions des utilisateurs pour une compétence
+[x] Validation changement de paradigme avec tableau de bord + liste selon filtre au lieu de grande liste de tous les étudiants.
+
+[x] Dashboard : Graphique du nombre d'étudiants compétents.
-[ ] Générer un tableau ou une liste propre
+[x] Dashboard : Graphique du nombre d'étudiants ayant reçu chaque possibilité d'évaluation sur l'échelle et de ceux n'en ayant pas reçu.
-[ ] Pouvoir changer de compétence via un champ de recherche dynamique
+[x] Dashboard : Nombre de demandes d'évaluation sur la compétence provenant des étudiants du cours.
-[ ] Pouvoir changer de compétence via des boutons précédent, suivant
+[ ] Liste d'étudiants selon des filtres sur le grade, la proficiency et la demande d'évaluation avec sélection de filtre multiples cumulatifs.
-[ ] Permettre de filtrer par proficiency et par grade
+[x] Traiter le cas où il n'y a pas de compétences dans le cours (renvoyer vers la matrice)
+
+[x] Pouvoir changer de compétence via un champ de recherche dynamique
+
+[x] Pouvoir changer de compétence via des boutons précédent, suivant
[ ] Générer un lien vers la page cpt x user
+[ ] Exclure l'enseignant des tableau de bord : ne prendre que les rôles étudiants
+
### Page cpt x user
[ ] Récupérer toutes les données (ne marchera sûrement pas)
diff --git a/competency_iena_competencies_2.php b/competency_iena_competencies_2.php
index 9a30adec4692a4be5ffe68b196562adb29af80fb..ba366ecf34e2fde42dfdb1ea0a1af9196eac6641 100644
--- a/competency_iena_competencies_2.php
+++ b/competency_iena_competencies_2.php
@@ -38,7 +38,6 @@ $students = $student->get_all_students_by_course($COURSE->id);
$student->get_student_by_id($studentid);
// Les compétences du cours.
-// Utiliser ça au cas où en appliquant un sort sur 'sortorder' dans la DB (voir params méthode) pour s'en servir pour trier les cpt dans l'ordre. Apparemment, ça trie dans l'ordre de base. Pour changer l'ordre : réordonner dans la page CPT native de moodle.
// $course_cpts = \core_competency\course_competency::list_competencies($COURSE->id);
// L'état des compétences du cours pour un utilisateur
@@ -59,8 +58,6 @@ foreach ($students as $stud) {
}
echo "</datalist>";
-$change_stud_url = $CFG->wwwroot."/blocks/competency_iena/competency_iena_competencies_2.php?courseid=".$courseid."&studentid=";
-
echo "<button class='btn btn-secondary m-l-1' id='prevStud'>Précédent</button>";
echo "<button class='btn btn-secondary m-l-1' id='nextStud'>Suivant</button>";
diff --git a/competency_iena_competency_students_2.php b/competency_iena_competency_students_2.php
index 3d5e2da293217ae2b64f4f18036e7480fd2f784e..9bf43b9ce41812b89b4d5c521981d33f6f3938dc 100644
--- a/competency_iena_competency_students_2.php
+++ b/competency_iena_competency_students_2.php
@@ -3,40 +3,207 @@
require_once('../../config.php');
// ENLEVER SI NON NECESSAIRE :
-require_once('entity/block_competency_iena_competency.php');
-require_once('entity/block_competency_iena_module.php');
-require_once('entity/block_competency_iena_ressource.php');
-require_once('entity/block_competency_iena_section.php');
+// require_once('entity/block_competency_iena_competency.php');
+// require_once('entity/block_competency_iena_module.php');
+// require_once('entity/block_competency_iena_ressource.php');
+// require_once('entity/block_competency_iena_section.php');
require_once('entity/block_competency_iena_student.php');
-global $COURSE, $DB;
+global $COURSE, $DB, $CFG;
$courseid = required_param('courseid', PARAM_INT);
$competencyid = optional_param('competencyid', 0, PARAM_INT);
-$url = new moodle_url('/blocks/competency_iena/competency_iena_competency_students.php', array('courseid' => $courseid, 'competencyid' => $competencyid));
+$grade = optional_param('grade', 'all', PARAM_ALPHANUM);
+$proficiency = optional_param('proficiency', 'all', PARAM_ALPHANUM);
+$review = optional_param('review', 'all', PARAM_ALPHANUM);
+$url = new moodle_url('/blocks/competency_iena/competency_iena_competency_students_2.php', array('courseid' => $courseid, 'competencyid' => $competencyid, 'grade' => $grade, 'proficiency' => $proficiency, 'review' => $review));
//$requete = $DB->get_record_sql('SELECT course FROM {block_competency_iena} WHERE id = ?', array($courseid));
-
$PAGE->set_pagelayout('course');
$PAGE->set_url($url);
-
-if (!has_capability('moodle/course:update', $context = context_course::instance($courseid), $USER->id)) {
+$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
+if (!has_capability('moodle/course:update', $context = context_course::instance($course->id), $USER->id)) {
$link = $CFG->wwwroot . '/course/view.php?id=' . $courseid;
header("Location: {$link}");
exit;
}
-
-$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
require_login($course, false, NULL);
$PAGE->set_title(get_string('title_plugin', 'block_competency_iena'));
-$PAGE->set_heading($OUTPUT->heading($COURSE->fullname, 2, 'headingblock header outline'));
-echo $OUTPUT->header();
-// require_once('view/view_competency_iena_competency_students.php');
-// $view = new view_competency_iena_competency_students();
-// echo $view->get_content($competencyid);
+/* Liste des compétences du cours */
+$course_cpts = \core_competency\course_competency::list_competencies($COURSE->id);
+
+if (count($course_cpts) === 0) {
+ $PAGE->set_heading($OUTPUT->heading($COURSE->fullname, 2, 'headingblock header outline'));
+ echo $OUTPUT->header();
+ echo "<p class='alert alert-warning'>Pour le moment, aucune compétence n'a été liée à ce cours. Pour lier des compétences au cours et les associer à des activités, rendez-vous dans la page <a href='{$CFG->wwwroot}/blocks/competency_iena/competency_iena_competencies_mgmt.php?courseid={$courseid}'>Gestion des compétences</a>. </p>";
+ echo $OUTPUT->footer();
+} else {
+
+ $current_cpt = new stdClass();
+ foreach ($course_cpts as $course_cpt) {
+ $current_cpt->id = $course_cpt->get('id');
+ if ( $current_cpt->id == $competencyid || $competencyid == 0 ) {
+ $current_cpt->shortname = $course_cpt->get('shortname');
+ $current_cpt->scale = $course_cpt->get_scale()->scale_items;
+ break;
+ }
+ }
+
+ $PAGE->set_heading($OUTPUT->heading($current_cpt->shortname, 2, 'headingblock header outline'));
+ $PAGE->requires->js("/blocks/competency_iena/js/datalist-polyfill.min.js");
+ $PAGE->requires->js("/blocks/competency_iena/js/cpt-x-studs.js");
+ echo $OUTPUT->header();
+
+ /* Les étudiants. */
+ $student_entity = new block_competency_iena_student();
+ $students = $student_entity->get_all_students_by_course($COURSE->id);
+ $count_students = count($students);
+ $student_ids = array();
+ foreach ($students as $stud) {
+ $student_ids[] = $stud->id;
+ }
+
+ echo "<div class='container-fluid'>";
+
+ /* ===== CHANGE COMPETENCY ===== */
+
+ echo "<div class='alert row' style='padding: 0;'>"; /* Début change competency. */
+ echo "<div class='col-12' style='padding-left: 0;'>";
+ echo "<form action='{$CFG->wwwroot}/blocks/competency_iena/competency_iena_competency_students_2.php' id='change_cpt_form' class='form-inline'>";
+ echo "<input type='text' hidden name='courseid' value='{$COURSE->id}'>";
+ echo "<span hidden id='competencyid'>{$current_cpt->id}</span>";
+ echo "<label class='m-r-1' for='competencyid_sel' style=''>Changer de compétence</label>";
+ echo "<input type='text' name='competencyid' id='competencyid_sel' value='' list='competency_list' class='form-control'>";
+ echo "<datalist id='competency_list' title='Select competency'>";
+ foreach ($course_cpts as $course_cpt) {
+ echo "<option value='{$course_cpt->get('shortname')} ({$course_cpt->get('id')})' data-value='{$course_cpt->get('id')}'>{$course_cpt->get('shortname')} ({$course_cpt->get('id')})</option>";
+ }
+ echo "</datalist>";
+ echo "<button class='btn btn-secondary m-l-1' id='prevCpt'>Précédent</button>";
+ echo "<button class='btn btn-secondary m-l-1' id='nextCpt'>Suivant</button>";
+ echo "</form>";
+ echo "</div>";
+ echo "</div>"; /* Fin change competency. */
+
+ /* ===== DASHBOARD ===== */
+
+ echo "<div class='alert alert-secondary row' style='padding-top: 1.5rem;'>"; /* Début tableau de bord. */
+
+ /* <<< PROFICIENCY SECTION >>> */
+ echo "<div class='col-12 col-lg-6'>";
+
+ /* Nombre d'enregistrements, donc d'étudiants, proficients pour la compétence courante. */
+ $count_proficients = $DB->count_records('competency_usercompcourse', [
+ 'courseid' => $COURSE->id,
+ 'proficiency' => 1,
+ 'competencyid' => $current_cpt->id
+ ]);
+
+ echo "<h2 class='h4'>Validé dans ce cours</h2>";
+
+ $chart = new \core\chart_pie();
+ $proficiency_serie = new core\chart_series('', [$count_proficients, $count_students - $count_proficients]);
+ $chart->set_doughnut(true);
+ $chart->add_series($proficiency_serie);
+ $chart->set_labels(["Validé", "Non validé"]);
+ echo $OUTPUT->render($chart);
+
+ echo "</div>"; /* proficiency section end */
+
+ /* <<< GRADE SECTION >>> */
+ echo "<div class='col-12 col-lg-6'>";
+ echo "<h2 class='h4'>Évaluations</h2>";
+
+ /* Nombre d'enregistrements, donc d'étudiants, de chaque grade sur la scale d'évaluation. */
+ $bd_grades = $DB->get_records('competency_usercompcourse', ['courseid' => $COURSE->id, 'competencyid' => $current_cpt->id], '', 'id, grade');
+
+ /* Constitution de la liste du compte de grade pour chaque possibilité. */
+ $grade_scale_counter = array();
+ $count_total_grades = 0;
+ foreach ($current_cpt->scale as $key => $scale_item) {
+ $grade_scale_counter[$key] = 0;
+ }
+ foreach ($bd_grades as $bd_grade) {
+ foreach ($grade_scale_counter as $grade_scale_item => $item_count) {
+ if ( $grade_scale_item + 1 == $bd_grade->grade ) {
+ $grade_scale_counter[$grade_scale_item]++;
+ $count_total_grades++;
+ break;
+ }
+ }
+ }
+ $grade_scale_counter[] = $count_students - $count_total_grades;
+ $scale_for_labels = $current_cpt->scale;
+ $scale_for_labels[] = "Non évalués";
+ /* Graphique MOODLE */
+ $chart = new core\chart_bar();
+ $grade_serie = new core\chart_series('', $grade_scale_counter);
+ $chart->add_series($grade_serie);
+ $chart->set_labels($scale_for_labels);
+ echo $OUTPUT->render($chart);
+ echo "</div>"; /* grade section end */
+
+ /* <<< TO REVIEW SECTION >>> */
+ echo "<div class='col-12'>";
+ $student_ids_implode = implode(",", $student_ids);
+ $reviews_count = $DB->count_records_select(
+ 'competency_usercomp',
+ "userid IN ({$student_ids_implode}) AND competencyid = {$current_cpt->id} AND status = 1",
+ null,
+ "COUNT('status')");
+
+ echo "<h2 class='h4'>Demandes d'évaluations <span class='badge badge-pill badge-primary' style=' border-radius: 0.15rem;'>$reviews_count</span></h2>";
+ echo "</div>"; /* to review section end */
+
+ echo "</div>"; /* Fin tableau de bord. */
+
+ /* ===== FILTERS ===== */
+
+ echo "<div class='alert alert-secondary row'>"; /* Début filtres. */
+ echo "<div class='col-12'>";
+
+ echo "<form class='form-inline'>";
+ echo "<label>Évaluation</label><select name='grade' class='custom-select mr-3'><option value='all'>Tous</option><option value='no'>Pas encore évalué</option><option value='0'>Not yet competent</option><option value='1'>Competent</option></select>";
+ echo "<label>Validé</label><select name='proficiency' class='custom-select mr-3'><option value='all'>Tous</option><option value='0'>Non</option><option value='1'>Oui</option></select>";
+ echo "<label>Évaluation demandée</label><select name='review' class='custom-select mr-3'><option value='all'>Tous</option><option value='0'>Non</option><option value='1'>Oui</option></select>";
+ echo "<button type='submit' class='btn btn-primary'>Chercher</button>";
+ echo "</form>";
+
+ echo "</div>";
+ echo "</div>"; /* Fin filtres. */
+
+ /* ===== STUDENT LIST ===== */
+
+ echo "<div class='row'>"; /* Début student list. */
+ echo "<div class='col-12'>";
+
+ echo "prout";
+
+ echo "</div>";
+ echo "</div>"; /* Fin student list. */
+
+ echo "</div>"; /* Fin du container bootstrap. */
+
+
+
+ /* L'état des compétences du cours pour un utilisateur */
+ // $user_course_competencies = \core_competency\api::list_user_competencies_in_course($COURSE->id, 4);
+ // $user_course_competencies = \core_competency\api::get_user_competency_in_course($COURSE->id, 4, 1);
+
+
+
+
+ /* ATTENTION : pour les deux vues */
+
+ /* ATTENTION : Les reviews demandées à lister, voire dans l'api list_user_competencies_to_review ou trouver si c'est dans l'objet de base */
+
+ /* ATTENTION : la compétence dans l'absolut versus dans le cours : ça apparait où ??? */
-echo "OYé";
+ /* list_course_modules_using_competency */
+ /* list_course_module_competencies_in_course_module */
+ /* list_course_module_competencies */
-echo $OUTPUT->footer();
+ echo $OUTPUT->footer();
+}
\ No newline at end of file
diff --git a/js/cpt-x-studs.js b/js/cpt-x-studs.js
new file mode 100644
index 0000000000000000000000000000000000000000..b56033bb819aad48759957d3131c37a47d0fc10a
--- /dev/null
+++ b/js/cpt-x-studs.js
@@ -0,0 +1,46 @@
+(function() {
+
+ /* Submit datalist selector to change current competency
+ on the dashboard listing avery student status regarding a particular competency. */
+
+ window.onload = function () {
+ var opts = document.getElementById('competency_list').childNodes;
+ var competencyid = document.getElementById('competencyid').innerHTML;
+ for (var i = 0; i < opts.length; i++) {
+ if (opts[i].dataset.value === competencyid) {
+ var prev = opts[i - 1] === undefined ? false : opts[i - 1].dataset.value;
+ var next = opts[i + 1] === undefined ? false : opts[i + 1].dataset.value;
+ if (prev === false) {
+ document.getElementById('prevCpt').setAttribute('disabled', 'disabled');
+ } else {
+ // document.getElementById('prevCpt').href += prev;
+ document.getElementById('prevCpt').dataset.prev = prev;
+ document.getElementById('prevCpt').onclick = function () {
+ document.getElementById('competencyid_sel').value = document.getElementById('prevCpt').dataset.prev;
+ }
+ }
+ if (next === false) {
+ document.getElementById('nextCpt').setAttribute('disabled', 'disabled');
+ } else {
+ // document.getElementById('nextCpt').href += next;
+ document.getElementById('nextCpt').dataset.next = next;
+ document.getElementById('nextCpt').onclick = function () {
+ document.getElementById('competencyid_sel').value = document.getElementById('nextCpt').dataset.next;
+ }
+ }
+ }
+ }
+ };
+
+ // remplace le nom de l'étu par son id dans la valeur de l'input puis soumet le formulaire
+ document.getElementById('competencyid_sel').oninput = function (e) {
+ var val = document.getElementById('competencyid_sel').value;
+ var opts = document.getElementById('competency_list').childNodes;
+ for (var i = 0; i < opts.length; i++) {
+ if (opts[i].value === val) {
+ document.getElementById('competencyid_sel').value = opts[i].dataset.value;
+ document.getElementById('change_cpt_form').submit();
+ }
+ }
+ };
+})()
\ No newline at end of file