diff --git a/amd/build/header.js b/amd/build/header.js
index deba9369a068c84bb47ec0c2f3af3a527cc1910e..26243b736c3cfbb0894f09ef68066247745ba0e6 100644
--- a/amd/build/header.js
+++ b/amd/build/header.js
@@ -27,6 +27,7 @@ define(['jquery', 'core/ajax', 'core/str'],
        	return{
        		
        		registerHeader:function(){
+                console.log("par ici ?");
                 var heightWrapper= $("#summary-wrapper").css("height");
         
                 if(parseInt(heightWrapper, 10) >= 144){
@@ -60,10 +61,14 @@ define(['jquery', 'core/ajax', 'core/str'],
                 else{
                     $("#button-collapse").hide();
                 }
+                var menu=$("#drawermenu .nav.navbar");
+                url=window.location.search;
+                console.log(url)
+                menu.append("<li class='nav-item'><a class='nav-link' href='"+url+"/course/format/iena/suivi_unit.php?courseid=3&sectionid=0&groupid=0'><i class='icon fa fa-table fa-fw' title='Notes'></i></a></li>");
+
 	    		
 	    		
        		}
-       		
 
        		
        		
diff --git a/amd/build/suivi-table.js b/amd/build/suivi-table.js
index 19bb33672c890947c4cd232d4dc77a91a4afd91f..15ba3a92c0fd16756d43184291a4fd80d863f62b 100644
--- a/amd/build/suivi-table.js
+++ b/amd/build/suivi-table.js
@@ -21,8 +21,8 @@
  * @copyright  2021 Myriam Delaruelle
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-define(['jquery'],
-       function($) {
+define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
+       function($, ajax, templates, str) {
        	var all_selected=false;
         nb_results=$("#table-body input").length;
         $("#select-actions-suivi-iena").prop("disabled", true);
@@ -30,15 +30,59 @@ define(['jquery'],
           
        		registerSelectAll:function(){
        			all_selected=false;
-            if(!$._data( $('#iena-select-all')[0], 'events' )){
-         			$('#iena-select-all').on('click', function(e){
-  					     select_all_studs(e);
-  	    		  });
-              $(".checkstudent").on("click", function(){
-                checkSelectActions();
-              })
+                if(!$._data( $('#iena-select-all')[0], 'events' )){
+             			$('#iena-select-all').on('click', function(e){
+      					     select_all_studs(e);
+      	    		  });
+                  $(".checkstudent").on("click", function(){
+                    checkSelectActions();
+                  })
+                }
+       		},
+                //Si l'option de détails au clic est activée, on register l'événement du clic
+            registerDetailsClick:function(){
+                completeUrl="http://localhost/moodle4/moodle/course/format/iena/suivi_unit.php?courseid=3&sectionid=7&groupid=0&filter=%E2%89%A50";
+                $(".pointer-help").on("click", function(e){
+                    e.stopPropagation();
+                    idmodule=$(this).data("module");
+                    idetudiant=$(this).parent().data("userid");
+                    nometudiant=$(this).siblings('.third-column-iena')[0].innerHTML;
+                    console.log(nometudiant);
+                    
+                    //$('#myModal').modal('show');
+                    //$('#myModal').modal('hide');
+                    $.ajax({ 
+                        url: completeUrl,
+                        data: {action: "details", idetudiant: idetudiant, idmodule: idmodule},
+                        type: 'post',
+                        success: function(request) { 
+                           parsedrequest=JSON.parse(request)
+                            console.log(parsedrequest);
+                            parsedrequest["student"]=nometudiant;
+                            
+                             //$("#modal-content").html(parsedrequest["completioninfos"]);
+                            //data=calcPercentage(JSON.parse(request));
+                            //On récupère les détails, on va les donner à la modale
+                            //
+                            templates.render('format_iena/modal-details', parsedrequest)
+                            .done(function(html, js){
+                                
+                                 $("#container-modal").html(html);
+                                 $('#details-modal').modal('toggle');
+                                 //templates.runTemplateJS(js);
+                                 //window.history.pushState('suivi',"", url);
+                                 //initHeaders();
+                                 
+                            })
+                            .fail(function(){
+                                loadMessage("error");
+                            }); 
+                        }
+                    });
+
+                })
             }
-       		}
+
        	}
 
    
diff --git a/amd/build/suivi.js b/amd/build/suivi.js
index 7535e2b4cb85c02e904f8c16763fbef9674a8b22..bca339df414a84a34a75224339f9626697911bd3 100644
--- a/amd/build/suivi.js
+++ b/amd/build/suivi.js
@@ -55,11 +55,52 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
                 });
                
 	    		
-	    		changeSection();
-                registerSelectAllActivitiesFilter();
-	    		/*calcPercentage(data);
-	    		changeCompletion();*/
-       		}
+	    		
+                //registerSelectAllActivitiesFilter();
+       		}, 
+
+       		//Evenement pour le selectall : créé une seule fois au chargement de la page
+		    registerSelectAllActivitiesFilter:function(){
+		        $('.selectallactivities').click(function() {
+		            if ($(".selectallactivities").is(':checked')) {
+		                checkAllActivitiesFilter();
+		                displayActivities();
+		            } else {
+		                $('.option').prop('checked', false);
+		                var message=str.get_string('selectedActivities', 'format_iena');
+		                $.when(message).done(function(localizedEditString) {
+		                    $(".dropdown-text").html('0 '+localizedEditString);
+		                }); 
+		                $(".select-text").html(' Select');
+		                displayActivities();
+		            }
+		        });
+		        //initActivityFilter();
+		    },
+		    registerSelectAllGroupsFilter:function(){
+		    	checkAllGroupsFilter();
+		    	$('.selectallgroups').click(function() {
+		            if ($(".selectallgroups").is(':checked')) {
+		                checkAllGroupsFilter();
+		            } else {
+		                $('.group-option').prop('checked', false);
+		                displayTotalGroupsFilter(); 
+		            	
+		            }
+		            changeGroup();
+		        });
+		    },
+		    initTable:function(){
+		    	initActivityFilter(false);
+		    	displayTotalActivitiesFilter(false);
+		    	displayTotalGroupsFilter(false);
+        		displayActivities(false);
+        		initGroupFilter(false);
+        		registerGroupFilter();
+        		changeSection(false);
+        		reloadTable(data);
+
+		    }
        		
 
        		
@@ -83,14 +124,6 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
     	groupid=$("#group-select").val();
     	sectionid=$("#section-select").val();
     	filter=$("#symbol-select").val() + $("#filter-select").val();
-        /*checkedActivities=$('input[name="options[]"]:checked');
-        activities=[];
-        for(var i=0; i< checkedActivities.length; i++){
-            if(checkedActivities[i].value >0){
-                activities.push(checkedActivities[i].value);
-            }
-            
-        }*/
     	completeUrl='suivi_unit.php?courseid='+courseid;
     	if(sectionid){
     		completeUrl+='&sectionid='+sectionid;
@@ -105,26 +138,40 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
     }
 
     function changeGroup(){
-    	completeUrl=getCompleteUrl();
+    	var completeUrl=getCompleteUrl();
+    	var groupscheckboxes= $('input[name="groupoptions[]"]:checked');
+    	var groupsid=[];
+    	for (var i = 0; i < groupscheckboxes.length; i++) {
+    		groupsid.push(groupscheckboxes[i].value);
+    	}
     	loadMessage("loading");
+    	if(groupsid.length==0){
+    		groupsid.push(-2);
+    	}
     	$.ajax({ url: completeUrl,
-        	data: {action: 'test'},
+        	data: {action: 'fetchgroups', groupsid:groupsid},
         	type: 'post',
         	success: function(request) { 
         		data=calcPercentage(JSON.parse(request));
-        		//changeCompletion();
+        		//initGroupFilter();
         		changeSection();
-         		//reloadTable(JSON.parse(request));	
+        		localStorage.setItem("groups",request);
+        		displayTotalGroupsFilter(false);
 			}
 		});
     }
 
   
-    function changeCompletion(){
+    function changeCompletion(changefilter=true){
     	symbol=$("#symbol-select").val();
     	filter=$("#filter-select").val();
     	data.count_results=0;
     	for(var i=0; i<data.students.length; i++){
+    		if(data.display_groups==1){
+    			data.students[i].display_groups=true;
+    		}
+
+    		
     		if(symbol=="<"){
     			if(data.students[i].percentage < filter){
     				data.count_results++;
@@ -172,12 +219,15 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
     		}
     		
     	}
-    	reloadTable(data);
+    	if(changefilter==true){
+    		reloadTable(data);
+    	}
+    	
     }
 
     //on va devoir calculer le pourcentage, check la completion et reload la table à chaque fois
 
-    function changeSection(){
+    function changeSection(changefilter=true){
     	loadMessage("loading");
     	sectionid=$("#section-select").val();
     	data.count_results=0;
@@ -198,12 +248,12 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
     		}
     	}
     	
-    	if(data.count_results==0){
+    	if(data.count_results==0 && changefilter ==true){
     		reloadTable(data);
     	}
     	else{
     		data=calcPercentage(data);
-    		changeCompletion();
+    		changeCompletion(changefilter);
     	}
         changeActivitiesDropdown(data.modules);
     }
@@ -214,16 +264,16 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
         html="";
         for (var i = 0; i<modules.length;i++){
             if(modules[i].visible){
-                html+='<li><label class="checkbox"><input type="checkbox" name="options[]" checked value='+modules[i].id+' class="option justone">'+modules[i].displayname+'</label></li>';
+                html+='<li><label class="checkbox"><input type="checkbox" name="options[]" checked value='+modules[i].id+' class="option justone-activity">'+modules[i].displayname+'</label></li>';
 
             }
         }
-        $(".iena-dynamic-options").html(html);
+        $(".iena-dynamic-activities").html(html);
         registerActivityFilter();
         checkAllActivitiesFilter();
     }
 
-    function displayActivities(){
+    function displayActivities(changefilter=true){
         var arrayActivitiesID=[];
         var activitiesToStore=[];
         var activities = $('input[name="options[]"]');
@@ -247,8 +297,10 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
           
         }
         localStorage.setItem("activities",JSON.stringify(activitiesToStore));
-        //changeCompletion();
-        reloadTable(data);
+        if(changefilter==true){
+        	reloadTable(data);
+        }
+        
     }
 
 
@@ -472,56 +524,21 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
 			data.students[i].percentage=Math.floor(100 * done / nb_modules);
 		}
 		return data;
-		//reloadTable(data);
 	}
 
-    //Evenement pour le selectall : créé une seule fois au chargement de la page
-    function registerSelectAllActivitiesFilter(){
-        $('.selectall').click(function() {
-            if ($(".selectall").is(':checked')) {
-                checkAllActivitiesFilter();
-                displayActivities();
-            } else {
-                $('.option').prop('checked', false);
-                var message=str.get_string('selectedActivities', 'format_iena');
-                $.when(message).done(function(localizedEditString) {
-                    $(".dropdown-text").html('0 '+localizedEditString);
-                }); 
-                $(".select-text").html(' Select');
-                displayActivities();
-            }
-        });
-        initActivityFilter();
-    }
-
 
     //On va recharger dynamiquement les options donc on doit recréer les événements à chaque fois qu'on change de section
     function registerActivityFilter(){
-        /*$("input[type='checkbox'].justone").change(function(){
-            var a = $("input[type='checkbox'].justone");
-            if(a.length == a.filter(":checked").length){
-                console.log("on va sélectionner tout du coup");
-                $('.selectall').prop('checked', true);
-                $(".select-text").html(' Deselect');
-            }
-            else {
-                console.log("on va décocher le sélectionner tout");
-                $('.selectall').prop('checked', false);
-                $(".select-text").html(' Select');
-            }
-            displayTotalActivitiesFilter();
-        });*/
-
-        $("input[type='checkbox'].justone").on('click', function(e){
+        $("input[type='checkbox'].justone-activity").on('click', function(e){
             e.stopPropagation();
-             var a = $("input[type='checkbox'].justone");
+             var a = $("input[type='checkbox'].justone-activity");
             if(a.length == a.filter(":checked").length){
-                $('.selectall').prop('checked', true);
+                $('.selectallactivities').prop('checked', true);
                 $(".select-text").html(' Deselect');
             }
             else {
 
-                $('.selectall').prop('checked', false);
+                $('.selectallactivities').prop('checked', false);
                 $(".select-text").html(' Select');
             }
             displayTotalActivitiesFilter();
@@ -546,48 +563,122 @@ define(['jquery', 'core/ajax', 'core/templates', 'core/str'],
                 $(".dropdown-text").html(total + ' '+localizedEditString);
             }); 
         }
-        //displayActivities();
-          
-
     }
   
     //Stocke le filtre des activités en localStorage pour ne pas avoir 50 id dans l'url
     //On fait bien attention à rétablir cocher le selectall si toutes les activités sont bien cochées
     function initActivityFilter(){
-
         if(localStorage.activities){
             var checkedActivities=JSON.parse(localStorage.activities);
-            var activities=$("input[type='checkbox'].justone");
-            if(activities.length===checkedActivities.length){
-
-                $(".selectall").prop("checked", true);
-                $("input[type='checkbox'].justone").prop("checked", true);
-            }
-            else{
-
-                $(".selectall").prop("checked", false);
-                for(var i=0; i<activities.length; i++){
-                    if(checkedActivities.includes(activities[i].value)){
-                        activities[i].checked=true;
-                    }
-                    else{
-                        activities[i].checked=false;
-                    }
-                }
+            var activities=$("input[type='checkbox'].justone-activity");
+            if($("input[type='checkbox'].justone-activity[value="+checkedActivities[0]+"]").length > 0){
+            	if(activities.length===checkedActivities.length ){
+	                $(".selectallactivities").prop("checked", true);
+	                $("input[type='checkbox'].justone-activity").prop("checked", true);
+	            }
+	            else{
+	                $(".selectallactivities").prop("checked", false);
+	                for(var i=0; i<activities.length; i++){
+	                    if(checkedActivities.includes(activities[i].value)){
+	                        activities[i].checked=true;
+	                    }
+	                    else{
+	                        activities[i].checked=false;
+	                    }
+	                }
+	            }
             }
+            
 
         }
-        displayTotalActivitiesFilter();
-        displayActivities();
+        //displayTotalActivitiesFilter();
+        //displayActivities();
     }
 
     //Coche toutes les activités quand on change de section
     function checkAllActivitiesFilter(){
-        $('.selectall').prop('checked', true);
+        $('.selectallactivities').prop('checked', true);
         $('.option').prop('checked', true);
         displayTotalActivitiesFilter();
         $(".select-text").html(' Deselect');
         
     }
+
+    function registerGroupFilter(){
+        $("input[type='checkbox'].justone-group").on('click', function(e){
+            e.stopPropagation();
+             var a = $("input[type='checkbox'].justone-group");
+            if(a.length == a.filter(":checked").length){
+                $('.selectallgroups').prop('checked', true);
+            }
+            else {
+                $('.selectallgroups').prop('checked', false);
+            }
+            displayTotalActivitiesFilter();
+            //displayActivities();
+        });
+
+        
+    }
+
+     function initGroupFilter(){
+        if(localStorage.groups){
+            var checkedGroups=JSON.parse(localStorage.groups);
+            var groups=$("input[type='checkbox'].justone-group");
+
+            if($("input[type='checkbox'].justone-group[value="+checkedGroups[0]+"]").length > 0){
+            	if(groups.length===checkedGroups.length ){
+	                $(".selectallgroups").prop("checked", true);
+	                $("input[type='checkbox'].justone-group").prop("checked", true);
+	            }
+	            else{
+	                $(".selectallgroups").prop("checked", false);
+	                for(var i=0; i<groups.length; i++){
+	                    if(checkedGroups.includes(groups[i].value)){
+	                        groups[i].checked=true;
+	                    }
+	                    else{
+	                        groups[i].checked=false;
+	                    }
+	                }
+	            }
+            }
+        }
+        else{
+        	checkAllGroupsFilter();
+        }
+        displayTotalActivitiesFilter();
+        //displayActivities();
+    }
+
+    //Coche tous les groupes quand le select all est coché
+    function checkAllGroupsFilter(){
+        $('.selectallgroups').prop('checked', true);
+        $('.group-option').prop('checked', true);
+        //changeGroup();
+        $(".select-text").html(' Deselect');
+        
+    }
+
+
+    //Update activities filter label
+    function displayTotalGroupsFilter(){
+        var total = $('input[name="groupoptions[]"]:checked').length;
+        if(total == $('input[name="groupoptions[]"]').length){
+            var message=str.get_string('allGroups', 'format_iena');
+            $.when(message).done(function(localizedEditString) {
+                $(".dropdown-text-group").html(localizedEditString);
+            }); 
+        }
+        else{
+            var message=str.get_string('selectedGroups', 'format_iena');
+            $.when(message).done(function(localizedEditString) {
+                $(".dropdown-text-group").html(total + ' '+localizedEditString);
+            }); 
+        }
+    }
+  
+
+
   
 });
diff --git a/classes/form/edittable_form.php b/classes/form/edittable_form.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5543dc6c557b39194acb5ac6f1e2f7a440b42d5
--- /dev/null
+++ b/classes/form/edittable_form.php
@@ -0,0 +1,81 @@
+<?php
+
+
+if (!defined('MOODLE_INTERNAL')) {
+    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
+}
+
+
+
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Default form for editing course section
+ *
+ * Course format plugins may specify different editing form to use
+ */
+class edittable_form extends moodleform {
+
+    function definition() {
+
+        $mform  = $this->_form;
+        $courseid = $this->_customdata['courseid'];
+        $display_groups = $this->_customdata['display_groups'];
+        $display_status = $this->_customdata['display_status'];
+        $display_details = $this->_customdata['display_details'];
+        $display_custom = $this->_customdata['display_custom'];
+        //$sectioninfo = $this->_customdata['cs'];
+
+        $radioarray = array();
+        $radioarray[] = $mform->createElement('advcheckbox', 'display_groups', get_string('enable'));
+        $mform->addGroup($radioarray, 'groups', get_string('display_groups', 'format_iena'), array(' '), false);
+        $mform->addHelpButton('groups', 'display_groups', 'format_iena');
+        $mform->setDefault('display_groups', $display_groups['value']);
+
+        $radioarray = array();
+        $radioarray[] = $mform->createElement('advcheckbox', 'display_custom', get_string('enable'));
+        $mform->addGroup($radioarray, 'custom', get_string('display_custom', 'format_iena'), array(' '), false);
+        $mform->addHelpButton('custom', 'display_custom', 'format_iena');
+        $mform->setDefault('display_custom', $display_custom['value']);
+
+        $radioarray = array();
+        $radioarray[] = $mform->createElement('advcheckbox', 'display_status', get_string('enable'));
+        $mform->addGroup($radioarray, 'status', get_string('display_status', 'format_iena'), array(' '), false);
+        $mform->addHelpButton('status', 'display_status', 'format_iena');
+        $mform->setDefault('display_status', $display_status['value']);
+
+        $radioarray = array();
+        $radioarray[] = $mform->createElement('advcheckbox', 'display_details', get_string('enable'));
+        $mform->addGroup($radioarray, 'details', get_string('display_details', 'format_iena'), array(' '), false);
+        $mform->addHelpButton('details', 'display_details', 'format_iena');
+        $mform->setDefault('display_details', $display_details['value']);
+    
+        $this->add_action_buttons(true, get_string('savechangesanddisplay'));
+        $mform->addElement('hidden', 'courseid', $courseid);
+        $mform->setType('courseid', PARAM_INT);
+
+        //$this->set_data($courseid);
+    }
+
+
+
+    /*function get_data() {
+        $mform =& $this->_form;
+       
+        if (!$this->is_cancelled() and $this->is_submitted() and $this->is_validated()) {
+            $data = $mform->exportValues();
+            unset($data['sesskey']); // we do not need to return sesskey
+            unset($data['_qf__'.$this->_formname]);   // we do not need the submission marker too
+            if (empty($data)) {
+                return NULL;
+            } else {
+                return (object)$data;
+            }
+        } else {
+            return NULL;
+        }
+    }*/
+
+
+
+}
diff --git a/classes/observer.php b/classes/observer.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1c0874eff55cc60e927e211b36e2b6693ad351f
--- /dev/null
+++ b/classes/observer.php
@@ -0,0 +1,31 @@
+<?php
+defined('MOODLE_INTERNAL') || die();
+
+
+class format_iena_observer {
+    /**
+     * Observer that monitors course module suppressed event and update the linked matrix competencies .
+     *
+     * @param \core\event\course_module_deleted $event the event object.
+     */
+    /*public static function course_module_deleted(\core\event\course_module_deleted $event) {
+        
+    }
+
+    public static function course_module_created(\core\event\course_module_created $event) {
+        
+    }*/
+
+    public static function user_module_completion(\core\event\course_module_completion_updated $event){
+        cache_helper::purge_by_event('iena_newprogress');
+    }
+
+    public static function group_add_member(\core\event\group_member_added $event){
+        cache_helper::purge_by_event('iena_newprogress');
+    }
+    public static function group_remove_member(\core\event\group_member_removed $event){
+        cache_helper::purge_by_event('iena_newprogress');
+    }
+
+
+}
diff --git a/classes/output/course_format_iena_table_option.php b/classes/output/course_format_iena_table_option.php
new file mode 100644
index 0000000000000000000000000000000000000000..d8a52c9953c81b32cad97f627865d57c0f323e89
--- /dev/null
+++ b/classes/output/course_format_iena_table_option.php
@@ -0,0 +1,275 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ *
+ * course_format_iena_sections
+ *
+ * @package    format_iena
+ * @copyright  2018 Softia/Université lorraine
+ * @author     vrignaud camille / Michaël Lebeau
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace format_iena\output;
+
+
+
+class course_format_iena_table_option {
+
+    const DISPLAY_GROUPS= "display_groups";
+    const DISPLAY_CUSTOM= "display_custom";
+    const DISPLAY_DETAILS= "display_details";
+    const DISPLAY_STATUS="display_status";
+
+
+    /** @var boolean */
+    
+    /**
+     * **/
+
+    public $optionname;
+    public $optionvalue;
+    public $courseid;
+    public $userid;
+    public $listoptions=array(
+        self::DISPLAY_GROUPS=>array("value"=>0),
+        self::DISPLAY_CUSTOM=>array("value"=>0),
+        self::DISPLAY_DETAILS=>array("value"=>0),
+        self::DISPLAY_STATUS=>array("value"=>0)
+    );
+
+    
+    /**
+     * [__construct description]
+     * @param boolean $displaygroups  [description]
+     * @param boolean $displaycustom  [description]
+     * @param boolean $displaydetails [description]
+     * @param boolean $displaystatus  [description]
+     * @param int     $idcourse       [description]
+     * @param int     $iduser         [description]
+     */
+    public function __construct(string $option = null, int $value=0, int $courseid = 0, int $userid= 0){
+        $this->optionname=$option;
+        $this->optionvalue=$value;
+        $this->courseid=$courseid;
+        $this->userid=$userid;
+    }
+
+    /**
+     * 
+     * @return array
+     * @throws dml_exception
+     */
+    public function get_options_by_course_id($courseid) {
+        global $DB;
+        $requete=[];
+        $requete = $DB->get_records('format_iena_options', ['courseid' => $courseid]);
+        return $requete;
+    }
+
+
+
+    public function create_array_option(){
+        global $DB;
+        $this->timecreated=time();
+
+         $arrayoptions=$DB->insert_record("format_iena_options", $this, true);
+         return $arrayoptions;
+    }
+
+    public function get_request_options(){
+         global $DB;
+ 
+         $arrayoptions = $DB->get_records('format_iena_options', ['courseid' => $this->courseid]);
+         $this->set_array_options(array_values($arrayoptions));
+         //return $this->get_array_options(array_values($arrayoptions));
+    }
+
+    /**
+     * formate le résultat de la requête qui récupère les options existantes
+     * @param  [array] $requestoptions [le tableau de résultat de la requête]
+     * @return [array]                 [un tableau d'objet qui contient nomoption => ["value" => value, "id"=>idoption]]
+     */
+    private function set_array_options($requestoptions){
+        if(is_object($requestoptions)){
+             $this->listoptions[$requestoptions->optionname]['value']=$requestoptions['optionvalue'];
+             $this->listoptions[$requestoptions->optionname]['id']=$requestoptions['id'];
+        }
+        else{
+
+            for($i=0; $i<count($requestoptions); $i++){
+                $this->listoptions[$requestoptions[$i]->optionname]['value']=$requestoptions[$i]->optionvalue;
+                $this->listoptions[$requestoptions[$i]->optionname]['id']=$requestoptions[$i]->id;
+            }
+        }
+        
+        //return $this->listoptions;
+    }
+
+    public function toArray() {
+        $vars = [];
+        foreach ($this as $varname => $varvalue) {
+
+            $vars[$varname] = $varvalue;
+        }
+        return $vars;
+    }
+
+    public function get_list_options(){
+        return $this->listoptions;
+    }
+ 
+
+    public function save_property($property, $value, $existingoption =false){
+        global $DB;
+        $this->setOptionname($property);
+        $this->setOptionvalue($value);
+        if($existingoption){
+            $this->timemodified=time();
+            $this->id=$existingoption;
+            return $result=$DB->update_record("format_iena_options", $this, true);
+        }
+        else{
+            $this->timecreated=time();
+            $this->timemodified=null;
+            return $result=$DB->insert_record("format_iena_options", $this, true);
+        }
+        
+        
+
+    }
+
+    public function check_option_checked($optionfromDB, $arrayfrominput){
+
+    }
+
+    public function check_option_unchecked(){
+
+    }
+
+    public function check_options_state($arrayfrominput){
+        foreach($this->listoptions as $option=>$arrayvalues){
+            if(isset($arrayvalues["id"])){
+                $this->save_property($option, $arrayfrominput->$option, $arrayvalues["id"]);
+            }
+            else if($arrayfrominput->$option != 0){
+                $this->save_property($option, $arrayfrominput->$option);
+            }
+        }
+    }
+  
+
+
+    /**
+     * @return mixed
+     */
+    public function getOptionname()
+    {
+        return $this->optionname;
+    }
+
+    /**
+     * @param mixed $optionname
+     *
+     * @return self
+     */
+    public function setOptionname($optionname)
+    {
+        $this->optionname = $optionname;
+
+        return $this;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getOptionvalue()
+    {
+        return $this->optionvalue;
+    }
+
+    /**
+     * @param mixed $optionvalue
+     *
+     * @return self
+     */
+    public function setOptionvalue($optionvalue)
+    {
+        $this->optionvalue = $optionvalue;
+
+        return $this;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getCourseid()
+    {
+        return $this->courseid;
+    }
+
+    /**
+     * @param mixed $courseid
+     *
+     * @return self
+     */
+    public function setCourseid($courseid)
+    {
+        $this->courseid = $courseid;
+
+        return $this;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getUserid()
+    {
+        return $this->userid;
+    }
+
+    /**
+     * @param mixed $userid
+     *
+     * @return self
+     */
+    public function setUserid($userid)
+    {
+        $this->userid = $userid;
+
+        return $this;
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getListoptions()
+    {
+        return $this->listoptions;
+    }
+
+    /**
+     * @param mixed $listoptions
+     *
+     * @return self
+     */
+    public function setListoptions($listoptions)
+    {
+        $this->listoptions = $listoptions;
+
+        return $this;
+    }
+}
diff --git a/classes/output/courseformat/content/section/header.php b/classes/output/courseformat/content/section/header.php
index 19ac53e4922321b1e70d43ea6801ac596ab08c17..0b9cb238543ea612aae88f44ad449aedc59566a7 100644
--- a/classes/output/courseformat/content/section/header.php
+++ b/classes/output/courseformat/content/section/header.php
@@ -129,16 +129,20 @@ class header extends header_base{
         }
         $context = context_course::instance($courseid);
         $groups=groups_get_all_groups($courseid);
+
         //$nb_modules = count($modules);
         if($display_button){
+            $link_suivi = new \stdClass();
             //si trop d'étudiants on va afficher le premier groupe dans le suivi
             if($this->count_students($context)>299 && count($groups)>0){
-                $link_suivi = $CFG->wwwroot . "/course/format/iena/suivi_unit.php?courseid=" . $courseid . "&sectionid=" . $section->id . "&groupid=".reset($groups)->id;
+              
+                $link_suivi->section=$CFG->wwwroot . "/course/format/iena/suivi_unit.php?courseid=" . $courseid . "&sectionid=" . $section->id . "&groupid=".reset($groups)->id;
             }
             else{
-                $link_suivi = $CFG->wwwroot . "/course/format/iena/suivi_unit.php?courseid=" . $courseid . "&sectionid=" . $section->id . "&groupid=0";
+                $link_suivi->section=$CFG->wwwroot . "/course/format/iena/suivi_unit.php?courseid=" . $courseid . "&sectionid=" . $section->id . "&groupid=0";
             }
-            
+             $link_suivi->full = $CFG->wwwroot . "/course/format/iena/suivi_unit.php?courseid=" . $courseid . "&sectionid=0&groupid=0";
+          
         }
             
             
diff --git a/classes/output/renderer.php b/classes/output/renderer.php
index db0b4f6efffb10305f22df177a3a4f1f8dddcd99..7074d2df8f911ddf5b00c3ad14116e166af50edd 100644
--- a/classes/output/renderer.php
+++ b/classes/output/renderer.php
@@ -107,6 +107,22 @@ class renderer extends section_renderer {
         echo $this->render_from_template('format_iena/send-message', $data);
     }
 
+    public function display_edit_page($data){
+        echo $this->render_from_template('format_iena/suivi-edit', $data);
+    }
+
+    /**
+     * Renders the activity information.
+     *
+     * Defer to template.
+     *
+     * @param \core_course\output\activity_information $page
+     * @return string html for the page
+     */
+    public function render_activity_information(\core_course\output\activity_information $page) {
+        $data = $page->export_for_template($this->output);
+        return $this->output->render_from_template('format_iena/iena_activity_info', $data);
+    }
 
 
 }
diff --git a/db/caches.php b/db/caches.php
new file mode 100644
index 0000000000000000000000000000000000000000..3686d169db80de5d9b1137651fce808102f5df8e
--- /dev/null
+++ b/db/caches.php
@@ -0,0 +1,11 @@
+<?php
+
+defined('MOODLE_INTERNAL') || die;
+
+$definitions = array(
+    'students' => array(
+        'mode' => cache_store::MODE_SESSION,
+        'invalidationevents' => ['iena_newprogress']
+
+    )
+);
diff --git a/db/events.php b/db/events.php
new file mode 100644
index 0000000000000000000000000000000000000000..79c28470b4b0f9fbe08d8a4f16010bb514c2d07e
--- /dev/null
+++ b/db/events.php
@@ -0,0 +1,27 @@
+<?php
+defined('MOODLE_INTERNAL') || die();
+
+$observers = array(
+    /*array(
+        'eventname'   => '\core\event\course_module_deleted',
+        'callback'    => 'block_competency_iena_observer::course_module_deleted',
+    ),
+    array(
+        'eventname'   => '\core\event\course_module_created',
+        'callback'    => 'block_competency_iena_observer::course_module_created',
+    ),*/
+    array(
+        'eventname'   => '\core\event\course_module_completion_updated',
+        'callback'    => 'format_iena_observer::user_module_completion',
+    ),
+    array(
+        'eventname'   => '\core\event\group_member_added',
+        'callback'    => 'format_iena_observer::group_add_member',
+    ),
+    array(
+        'eventname'   => '\core\event\group_member_removed',
+        'callback'    => 'format_iena_observer::group_remove_member',
+    )
+);
+
+?>
\ No newline at end of file
diff --git a/db/install.xml b/db/install.xml
new file mode 100644
index 0000000000000000000000000000000000000000..03743422bc87bbbed9cb53fa4602689cb0814e0a
--- /dev/null
+++ b/db/install.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<XMLDB PATH="course/format/iena/db" VERSION="20240131" COMMENT="XMLDB file for Moodle course/format/iena"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
+>
+  <TABLES>
+    <TABLE NAME="format_iena_options" COMMENT="Manage activity tracking table options">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
+        <FIELD NAME="optionname" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="optionvalue" TYPE="int" LENGTH="1" NOTNULL="false" SEQUENCE="false"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="8" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="8" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="timecreated" TYPE="int" LENGTH="16" NOTNULL="true" SEQUENCE="false"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="16" NOTNULL="false" SEQUENCE="false"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+      </KEYS>
+    </TABLE>
+  </TABLES>
+</XMLDB>
diff --git a/db/upgrade.php b/db/upgrade.php
index 4aceccdc28e07c7816651160f2a729b09117dd64..d55c89c64fa6c2d437e199ab9a88bf197563451d 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -27,7 +27,7 @@ function xmldb_format_iena_upgrade($oldversion) {
     global $CFG, $DB;
     $dbman = $DB->get_manager();
     $result = true;
-
+    error_log($oldversion);
     if ($oldversion < 2021220900) {
         // Support for old versions: we copy format options to the course_format_options table.
         try {
@@ -93,5 +93,29 @@ function xmldb_format_iena_upgrade($oldversion) {
         // Format_iena savepoint reached.
         upgrade_plugin_savepoint(true, 2021070600, 'format', 'iena');
     }
+      if ($oldversion < 2024012500) {
+
+        // Define field id to be added to format_iena.
+        $table = new xmldb_table('format_iena_options');
+        $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
+        $table->add_field('optionname', XMLDB_TYPE_CHAR, '10', null, XMLDB_NOTNULL, null, null, 'id');
+        $table->add_field('optionvalue', XMLDB_TYPE_INTEGER, '1', null, null, null, null, 'optionname');
+        $table->add_field('courseid', XMLDB_TYPE_INTEGER, '8', null, XMLDB_NOTNULL, null, null, 'optionvalue');
+        $table->add_field('userid', XMLDB_TYPE_INTEGER, '8', null, XMLDB_NOTNULL, null, null, 'courseid');
+        $table->add_field('timecreated', XMLDB_TYPE_INTEGER, '16', null, XMLDB_NOTNULL, null, null, 'userid');
+        $table->add_field('timemodified', XMLDB_TYPE_INTEGER, '16', null, null, null, null, 'timecreated');
+
+         $table->add_key('primary', XMLDB_KEY_PRIMARY, ['id']);
+
+        // Conditionally launch add field id.
+        if (!$dbman->table_exists($table)) {
+            $dbman->create_table($table);
+        }
+        
+
+        // Iena savepoint reached.
+        upgrade_plugin_savepoint(true, 2024012500, 'format','iena');
+    }
+
     return $result;
 }
diff --git a/entity/course_format_iena_message.php b/entity/course_format_iena_message.php
index c90c969069313df9e4edd16c58ec5a06334f11e8..c943138b856bb1e60d483e330f42c4d9a45ff401 100644
--- a/entity/course_format_iena_message.php
+++ b/entity/course_format_iena_message.php
@@ -23,7 +23,7 @@
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-require_once("{$CFG->libdir}/formslib.php");
+require_once($CFG->libdir.'/formslib.php');
 
 class course_format_iena_message extends moodleform {
     public function definition() {
diff --git a/lang/en/format_iena.php b/lang/en/format_iena.php
index ee7a3467cf67279c2ad72a13f7f239b4c28d6df8..342a03fd10d73de9f30a64a904fb8c3f2fe7f885 100644
--- a/lang/en/format_iena.php
+++ b/lang/en/format_iena.php
@@ -86,7 +86,7 @@ $string['status0'] = "Activity not completed";
 $string['status1'] = "Activity completed";
 $string['status2'] = "Activity completed and passed";
 $string['status3'] = "Activity completed but not passed";
-$string["send_message_title"] = "Sending a message to {{nb_results}} people";
+$string["send_message_title"] = 'Sending message to {$a} people';
 $string['display_course_infos'] = "Show/hide course information";
 $string['my_progress'] = "My progress in the course: ";
 $string['table_progress'] = "Tracking";
@@ -100,4 +100,22 @@ $string['message_dist_desc'] = "Configure default blended course message";
 $string['message_default_dist'] = "Default message distance learning";
 $string['formatenabled']="Course completion is disabled. You can enable it in the \"Course completion\" section here: ";
 $string['selectedActivities']="selected";
-$string['allActivities']="All";
\ No newline at end of file
+$string['allActivities']="All";
+$string['display_groups']="Display groups in a column";
+$string['display_custom']="Enable table customization ";
+$string['display_details']="Display assessments details on click";
+$string['display_status']="Enable status \"Waiting for an evaluation from me\"";
+$string['display_groups_help']="Add a column to the table which display the student's group";
+$string['display_custom_help']="This option enables the table customization and allows you to add colors to certain activities (just for you), or to define milestones (for all teachers in the course)";
+$string['display_details_help']="this option allows you to have the details of an assessment on click: grade, date of evaluation, evaluator, etc.";
+$string['display_status_help']="This option adds a new status \"Waiting for an evaluation from me\" which allows you to identify which activities have been completed by the student and require action from the teacher";
+$string['cachedef_students'] = 'Students list';
+$string['selectedGroups']="selected";
+$string['allGroups']="All";
+$string['allGroupsLabel']="All groups";
+$string['withoutGroup']="Without groups";
+$string['allActivitiesLabel']="All activities";
+$string['completion']="completion";
+$string['filter']="Filter";
+$string['messagesSent']="Messages sent";
+$string['messagesNotSent']="An error occured: the messages could not be sent";
\ No newline at end of file
diff --git a/lang/fr/format_iena.php b/lang/fr/format_iena.php
index 3222e080ffa39cf16b78b667c517b62e83d77203..32e9d09b06beb92f9767ee8229ccdfb76d3df4a5 100644
--- a/lang/fr/format_iena.php
+++ b/lang/fr/format_iena.php
@@ -86,7 +86,7 @@ $string['status0'] = "Activité non complétée";
 $string['status1'] = "Activité complétée";
 $string['status2'] = "Activité complétée et validée";
 $string['status3'] = "Activité complétée non validée";
-$string["send_message_title"] = "Envoi d'un message à {{nb_results}} personnes";
+$string["send_message_title"] = 'Envoi d\'un message à {$a} personnes';
 $string['display_course_infos'] = "Afficher/Masquer les informations du cours";
 $string['my_progress'] = "Ma progression dans le cours : ";
 $string['table_progress'] = "Suivi des étudiants";
@@ -100,4 +100,24 @@ $string['message_dist_desc'] = "Paramétrez le message qui sera envoyé par déf
 $string['message_default_dist'] = "Entrez ici le message qui sera envoyé à vos étudiants";
 $string['formatenabled']="L'achèvement de cours n'est pas activé. Vous pouvez l'activer dans la section \"Achèvement de cours\" des paramètres du cours : ";
 $string['selectedActivities']="sélectionnée(s)";
-$string['allActivities']="Toutes";
\ No newline at end of file
+$string['allActivities']="Toutes";
+$string['display_groups']="Afficher les groupes dans une colonne du tableau";
+$string['display_custom']="Activer la personnalisation du tableau";
+$string['display_details']="Afficher les détails d'une activité évaluée au clic";
+$string['display_status']="Activer le statut \"En attente d'évaluation de ma part\"";
+$string['display_groups_help']="Cette option ajoute une colonne dans le tableau contenant le nom du groupe de l'étudiant.";
+$string['display_custom_help']="Cette option active la personnalisation du tableau et permet d'ajouter des couleurs à certaines activités (personnel), ou de définir des jalons (pour tous les enseignants du cours)";
+$string['display_details_help']="Cette option permet à l'enseignant d'avoir les détails d'une évaluation au clic : note, date de l'évaluation, évaluateur...";
+$string['display_status_help']="Cette option ajoute un statut 'En attente d'évaluation de ma part qui permet de repérer quelles activités ont été complétées par l'étudiant et nécessite une action de la part de l'enseignant";
+$string['cachedef_students'] = 'La liste des étudiants du cours';
+$string['selectedGroups']="sélectionné(s)";
+$string['allGroups']="Tous";
+$string['allGroupsLabel']="Tous les groupes";
+$string['withoutGroup']="Sans groupe";
+$string['allActivitiesLabel']="Toutes les activités";
+$string['completion']="achèvement";
+$string['filter']="Filtre";
+$string['messagesSent']="Message(s) envoyé(s)";
+$string['messagesNotSent']="Une erreur s'est produite : le()s message(s) n'ont pas été envoyé(s)";
+
+
diff --git a/lib.php b/lib.php
index ad4fcd6b23e4432104f2d877cc0bf2b2e9fe3a0a..57d0dc67b7cd682a30483f5ce68a8588bd8ee026 100644
--- a/lib.php
+++ b/lib.php
@@ -34,8 +34,8 @@ class format_iena extends format_topics {
      */
     public function course_format_options($foreditform = false) {
         global $PAGE;
-        static $courseformatoptions = false;
-        if ($courseformatoptions === false) {
+        /*static $courseformatoptions = false;
+        if ($courseformatoptions === false) {*/
             $courseformatoptions['allmodulesbreadcrum'] = array(
                 'default' => 0,
                 'type' => PARAM_INT,
@@ -44,7 +44,7 @@ class format_iena extends format_topics {
                 'default' => 1,
                 'type' => PARAM_INT,
             );
-        }
+        //}
         if ($foreditform && !isset($courseformatoptions['coursedisplay']['label'])) {
             $choicetab = array();
             $choicetab['1'] = get_string('yes', 'format_iena');
@@ -131,7 +131,6 @@ class format_iena extends format_topics {
         global $PAGE;
 
         $elements = parent::create_edit_form_elements($mform, $forsection);
-
         if ($forsection) {
             $mform->removeElement('presence', false);
             $mform->removeElement('daterendu', false);
@@ -258,13 +257,13 @@ class format_iena extends format_topics {
      */
     public function update_section_format_options($data) {
         global $DB;
-
+        
         $objectsection = new stdClass();
         $objectsection->id = $data["id"];
         $sectionconfig = $this->get_format_options($objectsection);
 
         // If a date was set but we want to remove it.
-        if (!isset($data['daterenducheck']) && !isset($data['daterenducheck2'])) {
+        if ((!isset($data['daterenducheck']) && !isset($data['daterenducheck2'])) && (isset($data['daterendu']))) {
             if (array_key_exists('daterendu', $sectionconfig) && !empty($sectionconfig['daterendu'])) {
                 $data['daterendu'] = null;
             } else {
diff --git a/send_message.php b/send_message.php
index 6d359827026c606087eb0fae77f14e51f56fc323..9180af9272357b3fd93b1660e01169c4f7c90528 100644
--- a/send_message.php
+++ b/send_message.php
@@ -54,6 +54,7 @@ if (isset($_POST["back_url"])) {
 
 $data = new stdClass();
 $nb = $students != "" ? count( explode(",", $students) ) : 0;
+
 require_once('entity/course_format_iena_message.php');
 $sendmessage = new course_format_iena_message(null, array('back_url' => $backurl,
     'students' => $students));
@@ -61,7 +62,7 @@ $sendmessage = new course_format_iena_message(null, array('back_url' => $backurl
 if ($nb == 0) {
     $data->nb_results = 0;
 } else {
-    $data->nb_results = $nb;
+    $data->nb_results=$nb;
     $data->users_id = $students;
     $courseid = required_param('courseid', PARAM_INT);
     $data->link_cancel = $CFG->wwwroot . "/course/view.php?id=" . $courseid;
@@ -109,6 +110,7 @@ if ($sendmessage->is_cancelled()) {
                 }
             }
         }
+
         $backurl .= "&msg_success=true";
     } catch (Exception $e) {
         $backurl .= "&msg_failure=true";
diff --git a/styles.css b/styles.css
index 76a0a83b8c305f3220569a89f70166c8949b0729..bbc4785e5feb45f4f864feea4a937c4ff9129780 100644
--- a/styles.css
+++ b/styles.css
@@ -1,4 +1,4 @@
-
+/*style 4*/
 /* injecter ça dans le renderer au lieu de le faire ici 
 afin que ça n'impacte pas le reste de la plateforme */
 
@@ -221,6 +221,13 @@ ul.nav.navbar-nav.ml-auto {
     background: #02746C;
 }
 
+.iena-icon-suivi{
+	display: block;
+  min-width: 0;
+  padding: 6px 10px;
+  border-radius: 50px;
+}
+
 .right_info {
 	margin-left: auto;
     display: flex;
@@ -231,6 +238,12 @@ ul.nav.navbar-nav.ml-auto {
     margin-left:10px;
 }
 
+.right_info a:focus{
+	outline: none!important;
+	background: none!important;
+	box-shadow: none!important;
+}
+
 .section_action_menu.ml-auto{
     margin-left: 5px!important;
 }
@@ -821,7 +834,7 @@ th.th-rotate > div > span {
 }
 
 .stud_perc {
-	min-width: 45px;
+	min-width: 42px;
 	display: inline-block;
     text-align: right;
 }
@@ -908,7 +921,7 @@ tbody th{
 }
 
 
-#suivi thead .first-column-iena, #suivi thead .second-column-iena, #suivi thead .third-column-iena,#suivi thead .actions-column-iena{
+#suivi thead .first-column-iena, #suivi thead .second-column-iena, #suivi thead .third-column-iena,#suivi thead .actions-column-iena, #suivi thead .group-column-iena{
 	vertical-align: bottom;
 	padding-bottom: .5rem;
 }
@@ -959,6 +972,8 @@ tbody th{
 	font: var(--fa-font-solid); width: 100%; display: inline-block;text-align: center; 
 	color: white;
 	font-size: medium;
+	font-size: large;
+	font-weight: 900;
 }
 
 .iena-icon-distance::after{
@@ -966,6 +981,9 @@ tbody th{
 	font: var(--fa-font-solid); width: 100%; display: inline-block;text-align: center; 
 	color: white;
 	font-size: medium;
+	font-size: large;
+	font-weight: 950;
+
 }
 
 .iena-caption-sections > .iena-caption-icons, .iena-caption-sections > .iena-caption-icons > * {
@@ -981,10 +999,10 @@ tbody th{
   position: relative;
   overflow: auto;
   white-space: nowrap;
-  max-height: 600px;
+  max-height: 85vh;
   border:1px solid lightgrey;
   border-radius: 5px;
-  padding: 0 10px 10px 10px;
+  padding: 0 10px 10px 0px;
 }
 
 .first-column-iena, .second-column-iena, .actions-column-iena, .third-column-iena{
@@ -999,6 +1017,13 @@ th.first-column-iena, th.second-column-iena, th.actions-column-iena, th.third-co
     top: 0;
 }
 
+#table-body td.row-header{
+	z-index: 10;
+}
+#table-body th.col-header{
+	z-index: 11;
+}
+
 #partial-table{
 	margin-bottom: 20px;
 }
@@ -1030,6 +1055,10 @@ th.first-column-iena, th.second-column-iena, th.actions-column-iena, th.third-co
     border-color: #e9ecef;
 }
 
+.iena-filters #group-select{
+	max-width: 240px;
+}
+
 #count-selected-students{
     margin-top: 10px;
 }
@@ -1047,7 +1076,6 @@ th.first-column-iena, th.second-column-iena, th.actions-column-iena, th.third-co
 
 .iena-custom-dropdown .dropdown-menu{
     border-radius: 0 0 0.5rem 0.5rem; 
-    width:100%;
     max-height: 200px;
     overflow-y: auto;
 }
@@ -1071,13 +1099,13 @@ th.first-column-iena, th.second-column-iena, th.actions-column-iena, th.third-co
     top: 13px;
 }
 
-.iena-dynamic-options{
+.iena-dynamic-options, .iena-dynamic-activities{
     list-style: none;
     padding: 0;
     margin-left: 0;
 }
 
-.iena-dynamic-options label{
+.iena-dynamic-options label, .iena-dynamic-activities label{
     white-space: nowrap;
 text-overflow: ellipsis;
 width: 94%;
@@ -1139,6 +1167,8 @@ border-bottom: 1px solid #dee2e6;
     .right-info{
         flex-basis: 15%;
     }
+
+    
     .mobile-bouton-suivi{
         display: block;
         min-width: 1rem;
@@ -1171,3 +1201,21 @@ border-bottom: 1px solid #dee2e6;
     }
 } 
 
+
+
+/******************************************************** Paramètres du tableau de suivi ******************************************/
+#iena-suivi-edit .form-inline{
+	padding-top: calc(0.375rem + 1px);
+}
+
+
+/******************************************************** Modale dans le tableau de suivi ******************************/
+#modal-completion-infos{
+  padding: 10px 12px 15px 12px;
+  background-color: #efefef;
+  margin-bottom: 10px;
+}
+
+#iena-group-dropdown optgroup{
+	margin-left: 8px;
+}
\ No newline at end of file
diff --git a/suivi_edit.php b/suivi_edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..e040ad188aafe7a45d0f8840289db7e0c6e32f3a
--- /dev/null
+++ b/suivi_edit.php
@@ -0,0 +1,110 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+/**
+ *
+ * @package    format_iena
+ * @copyright  2018 Softia/Université lorraine
+ * @author     vrignaud camille / Thomas Fradet
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+use format_iena\output;
+
+
+define('NO_OUTPUT_BUFFERING', true);
+
+
+
+require_once('../../../config.php');
+require_once($CFG->dirroot. '\course\format\iena\classes\form\edittable_form.php');
+
+
+
+$PAGE->requires->css('/course/format/iena/styles.css');
+
+//On va déjà chercher en BDD s'il y a des options
+
+
+
+
+
+
+
+
+
+function init_page($course) {
+    global $PAGE;
+    // Defines the id of the course with a get parameter.
+    // Getting DB information (*)  of the course.
+
+    $PAGE->set_title($course->fullname);
+    $PAGE->set_heading($course->fullname . " – " .get_string('table_progress', 'format_iena'));
+    $PAGE->set_pagelayout('incourse');
+
+    // Cache le menu dans le header.
+    $coursenode = $PAGE->navbar->add(get_string('table_progress', 'format_iena'),
+        null, navigation_node::TYPE_CONTAINER, null, 'suiviena');
+    $coursenode->make_active();
+    $coursenode->force_open();
+
+}
+
+
+$courseid = required_param('courseid', PARAM_INT);
+// Define the url of the view.
+$url = new moodle_url('/course/format/iena/suivi_edit.php', array('courseid' => $courseid));
+$PAGE->set_url($url);
+$returnurl=new moodle_url('/course/format/iena/suivi_unit.php', array('courseid' => $courseid));
+
+$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
+require_login($course);
+
+
+$context = context_course::instance($COURSE->id);
+
+if (!has_capability('course/iena:suivi', $context = context_course::instance($courseid), $USER->id)) {
+    $link = $CFG->wwwroot . '/course/view.php?id=' . $courseid;
+    header("Location: {$link}");
+    exit;
+}
+
+
+
+    init_page($course, $PAGE);
+    
+    $data = [];
+    $obj=new \format_iena\output\course_format_iena_table_option();
+    $obj->setCourseid($courseid);
+    $obj->setUserid($USER->id);
+    $obj->get_request_options();
+    $arraycustomform=$obj->listoptions;
+    $arraycustomform["courseid"]=$courseid;
+    $mform= new edittable_form(null, $arraycustomform);
+    // Form processing and displaying is done here.
+
+    if ($mform->is_cancelled()) {
+        redirect($returnurl);
+    } else if ($fromform = $mform->get_data()) {
+        $obj->check_options_state($fromform);
+        redirect($returnurl);
+    }
+    echo $OUTPUT->header();
+
+    $data["form"]=$mform->render();
+    $renderer = $PAGE->get_renderer('format_iena');
+    $renderer->display_edit_page($data);
+    echo $OUTPUT->footer();
+
diff --git a/suivi_unit.php b/suivi_unit.php
index befe60c2b874870f676c679e7c750c5e40c75800..817e3699778d4e7b0c85da0a84abf126e82d5112 100644
--- a/suivi_unit.php
+++ b/suivi_unit.php
@@ -27,8 +27,16 @@ require_once('view/view_param_indicateur.php');
 require_once('entity/course_format_iena_section_ressources.php');
 require_once('entity/course_format_iena_sections.php');
 require_once('entity/course_format_iena_groups.php');
+require_once($CFG->dirroot.'/course/modlib.php');
+use core_completion\cm_completion_details;
 $PAGE->requires->css('/course/format/iena/styles.css');
 
+
+
+
+
+
+
 global $COURSE, $DB, $USER, $PAGE;
 
 function init_page($course) {
@@ -45,9 +53,10 @@ function init_page($course) {
         null, navigation_node::TYPE_CONTAINER, null, 'suiviena');
     $coursenode->make_active();
     $coursenode->force_open();
+
 }
 
-function get_groups($context, $activegroupid, $progress, $groups) {
+function get_groups($context, $activegroupids, $groups) {
     global $USER, $COURSE;
     // Groupe du GET provenant du sélecteur de la page du cours
     // ou premier groupe de l'utilisateur, ou groupe 0 (tous les groupes).
@@ -57,14 +66,16 @@ function get_groups($context, $activegroupid, $progress, $groups) {
     $currentusergroups = [];
     $othergroups = [];
     // Si pas de groupe dans le get ou groupe 0 (tous) mais pas le droit => premier groupe existant du user ou groupe 0 (tous).
-    if ($activegroupid == null || ($activegroupid == 0 &&
+    
+    /*if ($activegroupid == null || ($activegroupid == 0 &&
         !has_capability('course/iena:suivi_edit', $context, $USER->id)) ) {
         if ( count($currentusergroupsids) == 0 ) {
             $activegroupid = 0;
         } else {
             $activegroupid = $currentusergroupsids[0];
         }
-    }
+    }*/
+
     // Groupes du cours avec id, nom et liste des id utilisateur de tous les
     // membres (3 clefs d'un tableau de groupes : id, name, member).
 
@@ -72,10 +83,10 @@ function get_groups($context, $activegroupid, $progress, $groups) {
 
     foreach ($groups as $group) {
         // Récupération du nom du group actif au passage.
-        if ( $group->id == $activegroupid ) {
+        /*if ( $group->id == $activegroupid ) {
             $activegroupname = $group->name;
             $group->selected = 'selected';
-        }
+        }*/
         if (in_array($group->id, $currentusergroupsids)) {
             $currentusergroups[] = $group;
         } else {
@@ -83,7 +94,8 @@ function get_groups($context, $activegroupid, $progress, $groups) {
         }
     }
 
-    $groupsall->groups = $othergroups;
+
+    $groupsall->othergroups = $othergroups;
     $groupsall->current_user_groups = $currentusergroups;
     return $groupsall;
 
@@ -91,7 +103,7 @@ function get_groups($context, $activegroupid, $progress, $groups) {
 
 // Formate l'achèvement d'activités pour le tableau de suivi. Pour chaque étudiant, on aura
 // dans le bon ordre la liste des modules et le completionstate.
-function format_progress($progress, $modules, $groups, $activegroupid, $activesectionid) {
+function format_progress($progress, $modules, $groups, $activegroupids, $activesectionid) {
     global $CFG, $COURSE;
     $students = array();
     foreach ($progress as $proginfo) {
@@ -102,17 +114,24 @@ function format_progress($progress, $modules, $groups, $activegroupid, $activese
         $progressstudent->email = $proginfo->email;
         $progressstudent->progress = array();
         $progressstudent->report_link = $CFG->wwwroot . "/report/outline/user.php?id=" .
-            $progressstudent->id . "&course=" . $COURSE->id . "&mode=outline";
+        $progressstudent->id . "&course=" . $COURSE->id . "&mode=outline";
         $progressstudent->message_link = $CFG->wwwroot . "/message/index.php?id=" . $progressstudent->id;
 
-        if ($activegroupid == 0) {
+        //if ($activegroupid == 0) {
             $progressstudent->groups = "";
+            $progressstudent->groupsid=array();
             foreach ($groups as $group) {
                 if (in_array($progressstudent->id, $group->members)) {
-                    $progressstudent->groups .= $group->name . " ";
+                    if(empty( $progressstudent->groups)){
+                        $progressstudent->groups .= $group->name . "";
+                    }
+                    else{
+                        $progressstudent->groups .= ", " .$group->name . " ";
+                    }
+                    array_push( $progressstudent->groupsid, $group->id);
                 }
             }
-        }
+        //}
 
         foreach ($modules as $key => $module) {
             $moduleprogress = new StdClass();
@@ -127,8 +146,12 @@ function format_progress($progress, $modules, $groups, $activegroupid, $activese
 
             $progressstudent->progress[$key] = $moduleprogress;
         }
-
+        //On a les données de tous les étudiants, c'est ici qu'on filtre selon le groupe actif - DEPRECATED
+        /*if ($activegroupid == 0 || ($activegroupid>0 && in_array($activegroupid, $progressstudent->groupsid))) {
+            $students[] = $progressstudent;
+        }*/
         $students[] = $progressstudent;
+        
     }
 
     return $students;
@@ -142,7 +165,7 @@ function get_activities($completion, $activesectionid) {
         $module->id = $activity->id;
         $module->name = $activity->name;
         $displayname = format_string($activity->name, true, array('context' => $activity->context));
-        $module->displayname = strlen($displayname) > 30 ? mb_substr($displayname, 0, 29, 'UTF-8').'…' : $displayname;
+        $module->displayname = strlen($displayname) > 50 ? mb_substr($displayname, 0, 49, 'UTF-8').'…' : $displayname;
         $module->section = $activity->section;
         $modules[] = $module;
         if ($activity->section == $activesectionid || $activesectionid == 0 ) {
@@ -150,6 +173,7 @@ function get_activities($completion, $activesectionid) {
         } else {
             $module->visible = false;
         }
+
     }
     return $modules;
 }
@@ -174,7 +198,7 @@ function get_sections($activesectionid) {
     return $sections;
 }
 
-function set_filters($data, $filters, $symbols, $sections, $groups, $currentusergroups, $activegroupname, $activesectionid) {
+function set_filters($data, $filters, $symbols, $sections, $groups, $currentusergroups, $othergroups, $activesectionid) {
     if (isset($_GET['filter'])) {
         $filtercomplete = $_GET['filter'];
         $symbols[mb_substr($filtercomplete, 0, 1, 'UTF-8')]->selected = "selected";
@@ -187,30 +211,30 @@ function set_filters($data, $filters, $symbols, $sections, $groups, $currentuser
     $data['filters'] = array_values($filters);
     $data['symbols'] = array_values($symbols);
     $data["sections"] = $sections;
-    $data["groups"] = array_values($groups);
+    //Ici on récupère les groupes "autres" auxquels je n'appartiens pas
+    //$data["groups"] = array_values($groups);
+    $data["othergroups"]=$othergroups;
     $data['current_user_groups'] = $currentusergroups;
 
-    if ($activegroupname == "") {
-        $data['default_group'] = 'selected';
-    }
-
+   
+    $data['default_group'] = 'selected';
     $data['data'] = array();
     $data['data']["sections"] = $sections;
-    $data['data']["groups"] = array_values($groups);
+    //$data['data']["groups"] = array_values($groups);
     $data['data']['current_user_groups'] = $currentusergroups;
-    $data['data']['active_group_name'] = $activegroupname;
     $data['data']['active_section_id'] = $activesectionid;
 
+
     return $data;
 }
 
-function set_data($data, $modules, $progress, $groups, $activegroupid, $activesectionid) {
+function set_data($data, $modules, $progress, $groups, $activegroupsids, $activesectionid, $listoptions) {
     global $COURSE, $USER, $CFG;
 
     $data["modules"] = $modules;
     $countmodules = count($data["modules"]);
 
-    $data["students"] = format_progress($progress, $modules, $groups, $activegroupid, $activesectionid);
+    $data["students"] = format_progress($progress, $modules, $groups, $activegroupsids, $activesectionid);
     $countstudents = count($data["students"]);
 
     if ($countstudents > 0 && $countmodules > 0) {
@@ -222,6 +246,13 @@ function set_data($data, $modules, $progress, $groups, $activegroupid, $activese
     }
 
     $data['link_classicview'] = $CFG->wwwroot . "/report/progress/index.php?course=" . $COURSE->id;
+    $data['link_editview']=$CFG->wwwroot . "/course/format/iena/suivi_edit.php?courseid=" . $COURSE->id;
+    if($listoptions->listoptions['display_groups']["value"]){
+        $data["display_groups"]=1;
+    }
+    if($listoptions->listoptions['display_details']["value"]){
+        $data["display_details"]=1;
+    }
 
     // Pour le téléchargement du tableau ?
     if (!isset($data['data'])) {
@@ -278,6 +309,10 @@ $symbols = [
     ]
 ];
 
+//On s'occupe des options ici
+
+
+
 $courseid = required_param('courseid', PARAM_INT);
 // Define the url of the view.
 $url = new moodle_url('/course/format/iena/suivi_unit.php', array('courseid' => $courseid));
@@ -290,27 +325,51 @@ require_once($CFG->libdir . '/completionlib.php');
 $completion = new completion_info($course);
 $context = context_course::instance($COURSE->id);
 
+$listoptions=new \format_iena\output\course_format_iena_table_option();
+$listoptions->setCourseid($courseid);
+$listoptions->get_request_options();
+
 if (!has_capability('course/iena:suivi', $context = context_course::instance($courseid), $USER->id)) {
     $link = $CFG->wwwroot . '/course/view.php?id=' . $courseid;
     header("Location: {$link}");
     exit;
 }
 
-if (isset($_GET['groupid'])) {
-    $activegroupid = $_GET['groupid'];
+
+
+if (isset($_POST['groupsid'])) {
+    $activegroupsids = $_POST['groupsid'];
 } else {
-    $activegroupid = 0;
+    $activegroupsids = array(0);
+}
+
+
+$cache = cache::make('format_iena', 'students');
+
+//Si le progrès de chacun des groupes existe déjà en cache on va les charger, sinon on les récupère dans la BDD et on les stocke
+$arrayprogress=array();
+for($i=0; $i<count($activegroupsids); $i++){
+    if($cache->get($activegroupsids[$i]) !== false){
+        $progress=$cache->get($activegroupsids[$i]);
+       
+        
+    }
+    else{
+        $progressrequest = $completion->get_progress_all(
+            '',
+            array(),
+            $activegroupsids[$i],
+            'u.lastname ASC, u.firstname ASC',
+            '',
+            '',
+            $context
+        );
+        $cache->set($activegroupsids[$i], $progressrequest);
+        $progress=$progressrequest;
+    }
+     $arrayprogress=(object) array_unique(array_merge((array) $arrayprogress, (array) $progress), SORT_REGULAR);
 }
 
-$progress = $completion->get_progress_all(
-    '',
-    array(),
-    $activegroupid,
-    'u.lastname ASC, u.firstname ASC',
-    '',
-    '',
-    $context
-);
 
 $activesectionid = 0;
 // Section du get acquise depuis le clic sur l'indicateur dans la page du cours,
@@ -319,26 +378,90 @@ if (isset($_GET['sectionid'])) {
     $activesectionid = $_GET['sectionid'];
 }
 
-if ($activegroupid == 0) {
-    // On récupère les ids des membres parce que dans l'excel on veut savoir qui appartient à quel groupe.
-    $groups = groups_get_all_groups($COURSE->id, 0, 0, 'g.*', true);
-} else {
-    // On ne récupère pas les ids des membres.
-    $groups = groups_get_all_groups($COURSE->id, 0, 0, 'g.*', false);
-}
+// On récupère les ids des membres parce que dans l'excel on veut savoir qui appartient à quel groupe.
+$groups = groups_get_all_groups($COURSE->id, 0, 0, 'g.*', true);
+$renderer = $PAGE->get_renderer('format_iena');
 
-// If a post is sent trought the page.
-if (isset($_POST['action']) && !empty($_POST['action'])) {
+//Si on cherche les détails d'une activité
+if (isset($_POST['action']) && $_POST['action'] == "details") {
+    require_once($CFG->libdir . '/gradelib.php');
+    $data = [];
+    $idetu=$_POST['idetudiant'];
+    $idmodule=$_POST['idmodule'];
+    $modinfo = get_fast_modinfo($COURSE->id, $idetu);
+    $cm = $modinfo->get_cm($idmodule);
+    //Utile ?
+    $completioninfo = new \completion_info($COURSE);
+    $completiondetails = new cm_completion_details($completioninfo, $cm, $idetu);
+    $activitydates = \core\activity_dates::get_dates_for_module($cm, $idetu);
+
+    $activityinfo = new \core_course\output\activity_information($cm, $completiondetails, $activitydates);
+    //$activity = $activityinfo->export_for_template($renderer);
+
+    $activityhtml=$renderer->render_activity_information($activityinfo);
+    $gradesobject=array();
+    try{
+        $gradesobject=grade_get_grades($COURSE->id, 'mod', $cm->modname, $cm->instance, $idetu);
+    }
+    catch(Exception $e){
+        error_log($e);
+    }
+  
+    $lastgrade=array();
+
+    if(!empty($gradesobject)){
+        $lastgradeobject=end($gradesobject->items[0]->grades);
+       
+        if($lastgradeobject){
+            $lastgrade["lastgrade"]=$lastgradeobject->str_long_grade;
+            error_log($lastgrade["lastgrade"]);
+            $lastgrade["datelastgrade"]=$lastgradeobject->dategraded;
+        }
+
+        if(isset($gradesobject->items[0]->gradepass)){
+            $lastgrade["passgrade"]=number_format($gradesobject->items[0]->gradepass, 2, ',', ''); 
+        }
+        else{
+           
+        }
+        /*$lastgrade["passgrade"]=$gradesobject->items[0]->gradepass ? number_format($gradesobject->items[0]->gradepass, 2, ',', '') : null;*/
+      
+      error_log(print_r($data["grades"], true));
+    }
+
+    //en cas d'achèvement manuel on créé les petites pastilles vertes ou grises (terminé ou à faire)
+    //
+
+    $data =array();
+    $data['url']=strval($cm->url);
+    $data['completion']=strval($cm->completion);
+    $data["grades"]=$lastgrade;
+    $data["customcompletion"]=$cm->customdata;
+    $data["completioninfos"]=$activityhtml;
+    $data["completionstate"]=$completiondetails->get_overall_completion();
+    $data["competiondetails"] = $completiondetails;
+    $data["activityname"]=$cm->name;
+  
+    echo json_encode($data);
+} 
+// If a post is sent trought the page --> Si on change les filtres (de groupes), le template est appelé en JS
+else if (isset($_POST['action']) && !empty($_POST['action'])) {
     // Si on change les filtres.
     $data = [];
     $modules = get_activities($completion, $activesectionid);
-
-    $data = set_data($data, $modules, $progress, $groups, $activegroupid, $activesectionid);
+    
+    $data = set_data($data, $modules, $arrayprogress, $groups, $activegroupsids, $activesectionid, $listoptions);
+    
     echo json_encode($data);
 } else {
+
     init_page($course, $PAGE);
     echo $OUTPUT->header();
+
+    //$progress=$cache->get($activegroupids);
+    $progress=$arrayprogress;
     $data = [];
+    //Si la complétion du cours n'est pas activée on redirige l'enseignant vers l'interface pour l'activer
     if(!$COURSE->enablecompletion){
         $data["completion_enabled"]=0;
         $data["link_enable"]= "<a href='".$CFG->wwwroot . '/course/edit.php?id=' . $courseid."'>sur ce lien</a>";
@@ -350,24 +473,26 @@ if (isset($_POST['action']) && !empty($_POST['action'])) {
         
 
         $modules = get_activities($completion, $activesectionid);
-        $groupsall = get_groups($context, $activegroupid, $progress, $groups);
+        //Répartit les groupes en "mes groupes" et "les groupes dont je ne fais pas partie"
+        $groupsall = get_groups($context, $activegroupsids, $groups);
 
         if (isset($groupsall->current_user_groups) && !empty($groupsall->current_user_groups)) {
             $currentusergroups = $groupsall->current_user_groups;
         }
-        $groups = $groupsall->groups;
+        //$groups = $groupsall->groups;
         $sections = get_sections($activesectionid);
-        $data = set_filters($data, $filters, $symbols, $sections, $groups, $currentusergroups, $activegroupname, $activesectionid);
-        $data = set_data($data, $modules, $progress, $groups, $activegroupid, $activesectionid);
+
+        $data = set_filters($data, $filters, $symbols, $sections, array_values($groups), $groupsall->current_user_groups, $groupsall->othergroups, $activesectionid);
+        $data = set_data($data, $modules, $arrayprogress, $groups, $activegroupsids, $activesectionid, $listoptions);
 
         if (isset($_GET["msg_success"])) {
             $msg = $_GET["msg_success"];
             $data["msg_success"] = $msg;
         }
 
+      
 }
-    
-    $renderer = $PAGE->get_renderer('format_iena');
+ 
     $renderer->display_completion($data);
     echo $OUTPUT->footer();
 }
diff --git a/templates/courseformat/content/section/header.mustache b/templates/courseformat/content/section/header.mustache
index eeb3df42950fd7b9d0b567fa5973bc4e354581dd..44bd46dc8eee454d1669b0ec18a85ea99d30f035 100644
--- a/templates/courseformat/content/section/header.mustache
+++ b/templates/courseformat/content/section/header.mustache
@@ -116,9 +116,16 @@
         {{/date}}
 
         {{#link_suivi}}
-            <a href='{{link_suivi}}' style='color : white'>
-                <div style="display:block;" class="nb_pers set_height id_groupe0">Suivi étudiant</div>
+      
+            <a href='{{{full}}}' style='color : white'  data-toggle="tooltip" title="Suivi global">
+                <div style="display:block;" class="nb_pers set_height iena-icon-suivi"><i class="fa fa-tasks"></i></div>
                 <div class="nb_pers set_height mobile-bouton-suivi"><i class="fa fa-tasks"></i></div>
+            </a>
+            <a href='{{section}}' style='color : white'  data-toggle="tooltip" title="Suivi de la section">
+                <div style="display:block;" class="nb_pers set_height iena-icon-suivi"><i class="fa fa-table"></i></div>
+            </a>
+          
+                
 
             </a>
         {{/link_suivi}}
diff --git a/templates/drawers.mustache b/templates/drawers.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..8e155d8c908f5415be3df609c14774bc234dd5ee
--- /dev/null
+++ b/templates/drawers.mustache
@@ -0,0 +1,180 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template theme_boost/drawers
+
+    Boost drawer template.
+
+    Context variables required for this template:
+    * sitename - The name of the site
+    * output - The core renderer for the page
+    * bodyattributes - attributes for the body tag as a string of html attributes
+    * sidepreblocks - HTML for the blocks
+    * hasblocks - true if there are blocks on this page
+    * courseindexopen - true if the nav drawer should be open on page load
+    * regionmainsettingsmenu - HTML for the region main settings menu
+    * hasregionmainsettingsmenu - There is a region main settings menu on this page.
+
+    Example context (json):
+    {
+        "sitename": "Moodle",
+        "output": {
+            "doctype": "<!DOCTYPE html>",
+            "page_title": "Test page",
+            "favicon": "favicon.ico",
+            "main_content": "<h1>Headings make html validators happier</h1>"
+         },
+        "bodyattributes":"",
+        "sidepreblocks": "<h2>Blocks html goes here</h2>",
+        "hasblocks":true,
+        "courseindexopen": true,
+        "navdraweropen": false,
+        "blockdraweropen": true,
+        "regionmainsettingsmenu": "",
+        "hasregionmainsettingsmenu": false,
+        "addblockbutton": ""
+    }
+}}
+{{> theme_boost/head }}
+
+<body {{{ bodyattributes }}}>
+{{> core/local/toast/wrapper}}
+<div id="page-wrapper" class="d-print-block">
+
+    {{{ output.standard_top_of_body_html }}}
+
+    {{> theme_boost/navbar }}
+    {{#courseindex}}
+        {{< theme_boost/drawer }}
+            {{$id}}theme_boost-drawers-courseindex{{/id}}
+            {{$drawerclasses}}drawer drawer-left {{#courseindexopen}}show{{/courseindexopen}}{{/drawerclasses}}
+            {{$drawercontent}}
+                {{{courseindex}}}
+            {{/drawercontent}}
+            {{$drawerpreferencename}}drawer-open-index{{/drawerpreferencename}}
+            {{$drawerstate}}show-drawer-left{{/drawerstate}}
+            {{$tooltipplacement}}right{{/tooltipplacement}}
+            {{$closebuttontext}}{{#str}}closecourseindex, core{{/str}}{{/closebuttontext}}
+        {{/ theme_boost/drawer}}
+    {{/courseindex}}
+    {{#hasblocks}}
+        {{< theme_boost/drawer }}
+            {{$id}}theme_boost-drawers-blocks{{/id}}
+            {{$drawerclasses}}drawer drawer-right{{#blockdraweropen}} show{{/blockdraweropen}}{{/drawerclasses}}
+            {{$drawercontent}}
+                <section class="d-print-none" aria-label="{{#str}}blocks{{/str}}">
+                    {{{ addblockbutton }}}
+                    {{{ sidepreblocks }}}
+                </section>
+            {{/drawercontent}}
+            {{$drawerpreferencename}}drawer-open-block{{/drawerpreferencename}}
+            {{$forceopen}}{{#forceblockdraweropen}}1{{/forceblockdraweropen}}{{/forceopen}}
+            {{$drawerstate}}show-drawer-right{{/drawerstate}}
+            {{$tooltipplacement}}left{{/tooltipplacement}}
+            {{$drawercloseonresize}}1{{/drawercloseonresize}}
+            {{$closebuttontext}}{{#str}}closeblockdrawer, core{{/str}}{{/closebuttontext}}
+        {{/ theme_boost/drawer}}
+    {{/hasblocks}}
+    <div id="page" data-region="mainpage" data-usertour="scroller" class="drawers {{#courseindexopen}}show-drawer-left{{/courseindexopen}} {{#blockdraweropen}}show-drawer-right{{/blockdraweropen}} drag-container">
+        <div id="topofscroll" class="main-inner">
+            <div class="drawer-toggles d-flex">
+                {{#courseindex}}
+                    <div class="drawer-toggler drawer-left-toggle open-nav d-print-none">
+                        <button
+                            class="btn icon-no-margin"
+                            data-toggler="drawers"
+                            data-action="toggle"
+                            data-target="theme_boost-drawers-courseindex"
+                            data-toggle="tooltip"
+                            data-placement="right"
+                            title="{{#str}}opendrawerindex, core{{/str}}"
+                        >
+                            <span class="sr-only">{{#str}}opendrawerindex, core{{/str}}</span>
+                            {{#pix}} t/index_drawer, moodle {{/pix}}
+                        </button>
+                    </div>
+                {{/courseindex}}
+                {{#hasblocks}}
+                    <div class="drawer-toggler drawer-right-toggle ml-auto d-print-none">
+                        <button
+                            class="btn icon-no-margin"
+                            data-toggler="drawers"
+                            data-action="toggle"
+                            data-target="theme_boost-drawers-blocks"
+                            data-toggle="tooltip"
+                            data-placement="right"
+                            title="{{#str}}opendrawerblocks, core{{/str}}"
+                        >
+                            <span class="sr-only">{{#str}}opendrawerblocks, core{{/str}}</span>
+                            <span class="dir-rtl-hide">{{#pix}}t/blocks_drawer, core{{/pix}}</span>
+                            <span class="dir-ltr-hide">{{#pix}}t/blocks_drawer_rtl, core{{/pix}}</span>
+                        </button>
+                    </div>
+                {{/hasblocks}}
+            </div>
+            {{{ output.full_header }}}
+            {{#secondarymoremenu}}
+                <div class="secondary-navigation d-print-none">
+                    {{> core/moremenu}}
+                </div>
+            {{/secondarymoremenu}}
+            <div id="page-content" class="pb-3 d-print-block">
+                <div id="region-main-box">
+                    {{#hasregionmainsettingsmenu}}
+                    <div id="region-main-settings-menu" class="d-print-none">
+                        <div> {{{ regionmainsettingsmenu }}} </div>
+                    </div>
+                    {{/hasregionmainsettingsmenu}}
+                    <section id="region-main" aria-label="{{#str}}content{{/str}}">
+
+                        {{#hasregionmainsettingsmenu}}
+                            <div class="region_main_settings_menu_proxy"></div>
+                        {{/hasregionmainsettingsmenu}}
+                        {{{ output.course_content_header }}}
+                        {{#headercontent}}
+                            {{> core/activity_header }}
+                        {{/headercontent}}
+                        {{#overflow}}
+                            <div class="container-fluid tertiary-navigation">
+                                <div class="navitem">
+                                    {{> core/url_select}}
+                                </div>
+                            </div>
+                        {{/overflow}}
+                        {{{ output.main_content }}}
+                        {{{ output.activity_navigation }}}
+                        {{{ output.course_content_footer }}}
+
+                    </section>
+                </div>
+            </div>
+        </div>
+        {{> theme_boost/footer }}
+    </div>
+    {{{ output.standard_after_main_region_html }}}
+</div>
+
+</body>
+</html>
+{{#js}}
+M.util.js_pending('theme_boost/loader');
+require(['theme_boost/loader', 'theme_boost/drawer'], function(Loader, Drawer) {
+    Drawer.init();
+    M.util.js_complete('theme_boost/loader');
+    console.log("On ouvre le drawer");
+});
+{{/js}}
diff --git a/templates/iena_activity_info.mustache b/templates/iena_activity_info.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..bb7447ff96fd109b57c8c66c331d82277e5e4df6
--- /dev/null
+++ b/templates/iena_activity_info.mustache
@@ -0,0 +1,97 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template core_course/activity_info
+
+    Container to display activity information such as:
+      - Activity dates
+      - Activity completion requirements (automatic completion)
+      - Manual completion button
+
+    Example context (json):
+    {
+        "activityname": "Course announcements",
+        "hascompletion": true,
+        "uservisible": true,
+        "hasdates": true,
+        "isautomatic": true,
+        "istrackeduser": true,
+        "showmanualcompletion": true,
+        "activitydates": [
+            {
+                "label": "Opens:",
+                "timestamp": 1293876000
+            }
+        ],
+        "completiondetails": [
+             {
+                "statuscomplete": 1,
+                "description": "Viewed"
+            },
+            {
+                "statusincomplete": 1,
+                "description": "Receive a grade"
+            }
+        ]
+    }
+}}
+<div data-region="activity-information" data-activityname="{{activityname}}" class="activity-information">
+
+    {{#hascompletion}}
+        {{#uservisible}}
+            <div class="completion-info" data-region="completion-info">
+                {{#isautomatic}}
+                    <div class="automatic-completion-conditions" data-region ="completionrequirements" role="list" aria-label="{{#str}}completionrequirements, core_course, {{activityname}}{{/str}}">
+
+                        {{#completiondetails}}
+                            {{> core_course/completion_automatic }}
+                        {{/completiondetails}}
+                    </div>
+                {{/isautomatic}}
+                {{^isautomatic}}
+                    {{#overallcomplete}}
+                        <div class="automatic-completion-conditions" data-region="completionrequirements" role="list" aria-label="{{#str}}completionrequirements, core_course, {{activityname}}{{/str}}">
+
+                                <span class="badge badge-pill alert-success icon-no-margin" role="listitem">
+                                    <i class="icon fa fa-check fa-fw " aria-hidden="true"></i>
+                                    <strong>Terminé :</strong> <span class="font-weight-normal">Marquer l'activité comme terminée</span>
+                                </span>
+                        </div>
+                    {{/overallcomplete}}
+                    {{#overallincomplete}}
+                        <div class="automatic-completion-conditions" data-region="completionrequirements" role="list" aria-label="{{#str}}completionrequirements, core_course, {{activityname}}{{/str}}">
+
+                                <span class="badge badge-pill badge-light" role="listitem">
+                                    <strong>À faire&nbsp;:</strong> <span class="font-weight-normal">Marquer l'activité comme terminée</span>
+                                </span>
+                        </div>
+                    {{/overallincomplete}}
+                {{/isautomatic}}
+            </div>
+        {{/uservisible}}
+    {{/hascompletion}}
+
+    {{#hasdates}}
+    <div data-region="activity-dates" class="activity-dates">
+        <div class="description-inner">
+            {{#activitydates}}
+                {{>core_course/activity_date}}
+            {{/activitydates}}
+        </div>
+    </div>
+    {{/hasdates}}
+</div>
diff --git a/templates/local/drawers.mustache b/templates/local/drawers.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..8e155d8c908f5415be3df609c14774bc234dd5ee
--- /dev/null
+++ b/templates/local/drawers.mustache
@@ -0,0 +1,180 @@
+{{!
+    This file is part of Moodle - http://moodle.org/
+
+    Moodle is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Moodle is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+}}
+{{!
+    @template theme_boost/drawers
+
+    Boost drawer template.
+
+    Context variables required for this template:
+    * sitename - The name of the site
+    * output - The core renderer for the page
+    * bodyattributes - attributes for the body tag as a string of html attributes
+    * sidepreblocks - HTML for the blocks
+    * hasblocks - true if there are blocks on this page
+    * courseindexopen - true if the nav drawer should be open on page load
+    * regionmainsettingsmenu - HTML for the region main settings menu
+    * hasregionmainsettingsmenu - There is a region main settings menu on this page.
+
+    Example context (json):
+    {
+        "sitename": "Moodle",
+        "output": {
+            "doctype": "<!DOCTYPE html>",
+            "page_title": "Test page",
+            "favicon": "favicon.ico",
+            "main_content": "<h1>Headings make html validators happier</h1>"
+         },
+        "bodyattributes":"",
+        "sidepreblocks": "<h2>Blocks html goes here</h2>",
+        "hasblocks":true,
+        "courseindexopen": true,
+        "navdraweropen": false,
+        "blockdraweropen": true,
+        "regionmainsettingsmenu": "",
+        "hasregionmainsettingsmenu": false,
+        "addblockbutton": ""
+    }
+}}
+{{> theme_boost/head }}
+
+<body {{{ bodyattributes }}}>
+{{> core/local/toast/wrapper}}
+<div id="page-wrapper" class="d-print-block">
+
+    {{{ output.standard_top_of_body_html }}}
+
+    {{> theme_boost/navbar }}
+    {{#courseindex}}
+        {{< theme_boost/drawer }}
+            {{$id}}theme_boost-drawers-courseindex{{/id}}
+            {{$drawerclasses}}drawer drawer-left {{#courseindexopen}}show{{/courseindexopen}}{{/drawerclasses}}
+            {{$drawercontent}}
+                {{{courseindex}}}
+            {{/drawercontent}}
+            {{$drawerpreferencename}}drawer-open-index{{/drawerpreferencename}}
+            {{$drawerstate}}show-drawer-left{{/drawerstate}}
+            {{$tooltipplacement}}right{{/tooltipplacement}}
+            {{$closebuttontext}}{{#str}}closecourseindex, core{{/str}}{{/closebuttontext}}
+        {{/ theme_boost/drawer}}
+    {{/courseindex}}
+    {{#hasblocks}}
+        {{< theme_boost/drawer }}
+            {{$id}}theme_boost-drawers-blocks{{/id}}
+            {{$drawerclasses}}drawer drawer-right{{#blockdraweropen}} show{{/blockdraweropen}}{{/drawerclasses}}
+            {{$drawercontent}}
+                <section class="d-print-none" aria-label="{{#str}}blocks{{/str}}">
+                    {{{ addblockbutton }}}
+                    {{{ sidepreblocks }}}
+                </section>
+            {{/drawercontent}}
+            {{$drawerpreferencename}}drawer-open-block{{/drawerpreferencename}}
+            {{$forceopen}}{{#forceblockdraweropen}}1{{/forceblockdraweropen}}{{/forceopen}}
+            {{$drawerstate}}show-drawer-right{{/drawerstate}}
+            {{$tooltipplacement}}left{{/tooltipplacement}}
+            {{$drawercloseonresize}}1{{/drawercloseonresize}}
+            {{$closebuttontext}}{{#str}}closeblockdrawer, core{{/str}}{{/closebuttontext}}
+        {{/ theme_boost/drawer}}
+    {{/hasblocks}}
+    <div id="page" data-region="mainpage" data-usertour="scroller" class="drawers {{#courseindexopen}}show-drawer-left{{/courseindexopen}} {{#blockdraweropen}}show-drawer-right{{/blockdraweropen}} drag-container">
+        <div id="topofscroll" class="main-inner">
+            <div class="drawer-toggles d-flex">
+                {{#courseindex}}
+                    <div class="drawer-toggler drawer-left-toggle open-nav d-print-none">
+                        <button
+                            class="btn icon-no-margin"
+                            data-toggler="drawers"
+                            data-action="toggle"
+                            data-target="theme_boost-drawers-courseindex"
+                            data-toggle="tooltip"
+                            data-placement="right"
+                            title="{{#str}}opendrawerindex, core{{/str}}"
+                        >
+                            <span class="sr-only">{{#str}}opendrawerindex, core{{/str}}</span>
+                            {{#pix}} t/index_drawer, moodle {{/pix}}
+                        </button>
+                    </div>
+                {{/courseindex}}
+                {{#hasblocks}}
+                    <div class="drawer-toggler drawer-right-toggle ml-auto d-print-none">
+                        <button
+                            class="btn icon-no-margin"
+                            data-toggler="drawers"
+                            data-action="toggle"
+                            data-target="theme_boost-drawers-blocks"
+                            data-toggle="tooltip"
+                            data-placement="right"
+                            title="{{#str}}opendrawerblocks, core{{/str}}"
+                        >
+                            <span class="sr-only">{{#str}}opendrawerblocks, core{{/str}}</span>
+                            <span class="dir-rtl-hide">{{#pix}}t/blocks_drawer, core{{/pix}}</span>
+                            <span class="dir-ltr-hide">{{#pix}}t/blocks_drawer_rtl, core{{/pix}}</span>
+                        </button>
+                    </div>
+                {{/hasblocks}}
+            </div>
+            {{{ output.full_header }}}
+            {{#secondarymoremenu}}
+                <div class="secondary-navigation d-print-none">
+                    {{> core/moremenu}}
+                </div>
+            {{/secondarymoremenu}}
+            <div id="page-content" class="pb-3 d-print-block">
+                <div id="region-main-box">
+                    {{#hasregionmainsettingsmenu}}
+                    <div id="region-main-settings-menu" class="d-print-none">
+                        <div> {{{ regionmainsettingsmenu }}} </div>
+                    </div>
+                    {{/hasregionmainsettingsmenu}}
+                    <section id="region-main" aria-label="{{#str}}content{{/str}}">
+
+                        {{#hasregionmainsettingsmenu}}
+                            <div class="region_main_settings_menu_proxy"></div>
+                        {{/hasregionmainsettingsmenu}}
+                        {{{ output.course_content_header }}}
+                        {{#headercontent}}
+                            {{> core/activity_header }}
+                        {{/headercontent}}
+                        {{#overflow}}
+                            <div class="container-fluid tertiary-navigation">
+                                <div class="navitem">
+                                    {{> core/url_select}}
+                                </div>
+                            </div>
+                        {{/overflow}}
+                        {{{ output.main_content }}}
+                        {{{ output.activity_navigation }}}
+                        {{{ output.course_content_footer }}}
+
+                    </section>
+                </div>
+            </div>
+        </div>
+        {{> theme_boost/footer }}
+    </div>
+    {{{ output.standard_after_main_region_html }}}
+</div>
+
+</body>
+</html>
+{{#js}}
+M.util.js_pending('theme_boost/loader');
+require(['theme_boost/loader', 'theme_boost/drawer'], function(Loader, Drawer) {
+    Drawer.init();
+    M.util.js_complete('theme_boost/loader');
+    console.log("On ouvre le drawer");
+});
+{{/js}}
diff --git a/templates/modal-details.mustache b/templates/modal-details.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..41be416d56c0306b9399a7ee6f4d9a58c83ca170
--- /dev/null
+++ b/templates/modal-details.mustache
@@ -0,0 +1,51 @@
+<div class="modal fade" id="details-modal" role="dialog">
+	<div class="modal-dialog modal-lg">
+
+		<!-- Modal content-->
+		<div class="modal-content">
+			<div class="modal-header">
+				<h4 class="modal-title">Détails de l'activité</h4>
+				<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+			</div>
+			<div class="modal-body">
+				<div class='row'>
+					
+					<div class='col-md-12 cpt-col'>
+						
+						<div><b>Etudiant : </b>{{student}}</div>
+						<div><b>Activité : </b>{{activityname}}</div>
+						<label><b>Modalités d'achèvements :</b></label>
+						<div id="modal-completion-infos">{{{completioninfos}}}
+						</div>
+
+						{{#grades}}
+						
+							{{#lastgrade}}
+							<div><b>Dernière note : </b> {{lastgrade}}</div>
+							{{/lastgrade}}
+							{{#passgrade}}
+							<div><b>Note de passage : </b> {{passgrade}}</div>
+							{{/passgrade}}
+						{{/grades}}
+						<div><i class="fa fa-external-link" aria-hidden="true"></i> Aller à l'activité : <a href="{{url}}" target="_blank">{{activityname}}</a></div>
+					<br>
+						<div class="iena-footer-cpt">
+							
+							<div class='align_center'>
+						<button class='btn btn-secondary' data-dismiss="modal">Fermer</button>
+					
+					</div>
+						</div>
+						
+					</div>
+
+				</div>
+			</div>
+
+		</div>
+	</div>
+
+
+	
+
+</div>
\ No newline at end of file
diff --git a/templates/send-message.mustache b/templates/send-message.mustache
index da29ba1a9d6333137c9554de797b899a9ba1272d..e0117da85bac3f8caa160b8471f1dc66c8e0f4d9 100644
--- a/templates/send-message.mustache
+++ b/templates/send-message.mustache
@@ -1,7 +1,6 @@
 <div>
 	{{#nb_results}}
-		<h2>{{# str }} send_message_title, format_iena {{/ str}}</h2>
-		
+		<h2>{{#str}} send_message_title, format_iena, {{nb_results}} {{/str}}</h2>
 		<p>Envoi d'un message à tous les étudiants précédemment sélectionnés. Les informations suivantes seront automatiquement ajoutées au message&nbsp;: nom du cours, lien vers le cours, nom du l'enseignant émetteur du message (vous). </p>
 		<p>L'étudiant recevra le message dans le chat et pourra être notifié par mail s'il n'est pas connecté au moment où le message est envoyé.</p>
 		<form class="m-t-1"  method="post">
diff --git a/templates/suivi-edit.mustache b/templates/suivi-edit.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..16e3d9bb433fd268847569f3769947d398e355f8
--- /dev/null
+++ b/templates/suivi-edit.mustache
@@ -0,0 +1,4 @@
+<div id="iena-suivi-edit">
+	<h2>Modifier les paramètres du suivi</h2>
+	{{{form}}}
+</div>
\ No newline at end of file
diff --git a/templates/suivi-table.mustache b/templates/suivi-table.mustache
index 3d0646a7a00945833142a5f34676769fab741d81..718e82e622c446f5562f50c32c4505f61a393440 100644
--- a/templates/suivi-table.mustache
+++ b/templates/suivi-table.mustache
@@ -6,10 +6,13 @@
 				<tr id="modules">
 					
 					
-					<th id="first-column-head" class="first-column-iena"> <input type="checkbox" id="iena-select-all" ></th>
-					<th class="second-column-iena">%</th>
-					<th class="actions-column-iena">Actions</th>
-					<th class="third-column-iena">Etudiants</th>
+					<th id="first-column-head " class="first-column-iena col-header"> <input type="checkbox" id="iena-select-all" ></th>
+					<th class="second-column-iena col-header">%</th>
+					<th class="actions-column-iena col-header">Actions</th>
+					<th class="third-column-iena col-header">Etudiants</th>
+					{{#display_groups}}
+					<th class="group-column-iena col-header">Groupes</th>
+					{{/display_groups}}
 					{{#modules}}
 						{{#visible}}
 							<th class="th-rotate" data-fullname="{{name}}" data-section="{{section}}">
@@ -27,41 +30,72 @@
 				{{#students}}
 					{{#visible}}
 						<tr data-userid="{{id}}" data-percent={{percentage}}>
-							<td class="first-column-iena">
+							<td class="first-column-iena row-header">
 								<input type="checkbox" class="checkstudent" name="checkstudent" value="{{id}}">
 							</td>
-							<td class="second-column-iena">
+							<td class="second-column-iena row-header">
 								<span class="stud_perc">{{percentage}} %</span>
 							</td>
-							<td class="actions-column-iena">
+							<td class="actions-column-iena row-header">
 								<a href="{{report_link}}" target="_blank"><i class="icon fa fa-graduation-cap fa-fw"></i></a>
 								<a href="{{message_link}}" target="_blank"><i class="icon fa fa-envelope fa-fw"></i></a>
 							</td>
-							<td class="third-column-iena">
+							<td class="third-column-iena row-header">
 								{{firstname}} {{lastname}}
 								
 							</td>
+							{{#display_groups}}
 
+							<td class="third-column-iena row-header">{{groups}}</td>
+							{{/display_groups}}
+
+	
 							{{#progress}}
 								{{#visible}}
-									<td title="{{namemodule}}" data-section="{{id}}" class="pointer-help state-{{completionstate}}"><span class="icon-progress"></span></td>
+									<td title="{{namemodule}}" data-section="{{id}}" data-module="{{idmodule}}" class="pointer-help state-{{completionstate}}"><span class="icon-progress"></span></td>
 								{{/visible}}
 							{{/progress}}
 						</tr>
 					{{/visible}}
 				{{/students}}
+				{{^students}}
+				
+					<tr >
+							
+							<td colspan=4 class="row-header" style="text-align: center;font-style: oblique;">
+								Il n'y a aucun étudiant dans le cours
+								
+							</td>
+							{{#modules}}
+								{{#visible}}
+							
+									<td  class="pointer-help state-0"><span class="icon-progress"></span></td>
+									{{/visible}}
+							{{/modules}}
+								
+						</tr>
+
+				{{/students}}
 			</tbody>
 		</table>
 	</div>
 
 <p id="count-selected-students">0 résultat(s) sélectionnés sur {{count_results}}</p>
-{{/count_results}}
-{{^count_results}}
-	<div class="alert alert-primary">Il n'y a pas de résultats correspondants aux filtres sélectionnés</div>
-{{/count_results}}
 {{#js}}
 require(['format_iena/suivi-table'], function(module) {
     module.registerSelectAll();
+});
+{{/js}}
+{{#display_details}}
+<div id="container-modal"></div>
+{{#js}}
+require(['format_iena/suivi-table'], function(module) {
+    module.registerDetailsClick();
 
 });
-{{/js}}
\ No newline at end of file
+{{/js}}
+{{/display_details}}
+{{/count_results}}
+{{^count_results}}
+	<div class="alert alert-primary">Il n'y a pas de résultats correspondants aux filtres sélectionnés</div>
+{{/count_results}}
diff --git a/templates/suivi.mustache b/templates/suivi.mustache
index d7002c41daf1a0c3e238852b4723fa5c8d2e75d8..0e84aa4b894cc2d292327af8688624bf13a3c967 100644
--- a/templates/suivi.mustache
+++ b/templates/suivi.mustache
@@ -18,7 +18,10 @@
 							{{/link_bulkcompletion}}
 							<div class="dropdown-item">
 						    	<a href="{{link_classicview}}" class="" role="menuitem"><i class="icon fa fa-pencil fa-fw " aria-hidden="true"></i>Vue classique</a>
-							</div>                                      
+							</div>         
+							<div class="dropdown-item">
+						    	<a href="{{link_editview}}" class="" role="menuitem"><i class="icon fa fa-eye fa-fw " aria-hidden="true"></i>Paramètres du tableau</a>
+							</div>                                  
 		                </div>
 		            </div>
 		        </div>
@@ -52,16 +55,17 @@
 			  <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown"><span class="dropdown-text">{{# str }} allActivities, format_iena {{/ str}}</span>
 			  <span class="caret"></span></button>
 				<ul class="dropdown-menu dropdown-menu-form" id="iena-activities-dropdown">
-				<li><label class="checkbox"><input type="checkbox" class="selectall" checked value='all'>Toutes les activités</label></li>
-				<li class="divider"></li>
-				<ul class="iena-dynamic-options">
-				{{#modules}}
-					{{#visible}}
-  						<li><label class="checkbox"><input type="checkbox" name="options[]" value={{id}} class="option justone">{{displayname}}</label></li>
-  					{{/visible}}
-				{{/modules}}
+					<li><label class="checkbox">
+						<input type="checkbox" class="selectallactivities" checked value='all'>{{# str }} allActivitiesLabel, format_iena {{/ str}}</label></li>
+					<li class="divider"></li>
+					<ul class="iena-dynamic-activities">
+					{{#modules}}
+						{{#visible}}
+	  						<li><label class="checkbox"><input type="checkbox" name="options[]" value={{id}} class="option justone-activity">{{displayname}}</label></li>
+	  					{{/visible}}
+					{{/modules}}
+					</ul>
 				</ul>
-		</ul>
 		</div>
 
 	</div>
@@ -71,32 +75,49 @@
 		<div class="input-group-prepend">
 			<div class="input-group-text">Groupes</div>
 		</div>
-		<select class="custom-select mr-sm-2" id="group-select" name="groupid">
+		<div class="dropdown mr-sm-2 iena-custom-dropdown" id="group-select" name="groupid">
+		<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
+		<span class="dropdown-text-group">Tous les groupes</span>
+		<span class="caret"></span></button>
+		<ul class="dropdown-menu dropdown-menu-form" id="iena-group-dropdown">
+			<li>
+				<label class="checkbox">
+				<input type="checkbox" class="selectallgroups" checked value='0' {{default_group}}>{{# str }} allGroupsLabel, format_iena {{/ str}}</label>
+			</li>
 			
-			<option value="0" {{default_group}}>Tous</option>
+			<li class="divider"></li>
+			<li>
+				<label class="checkbox">
+				<input type="checkbox" class="selectwithoutgroups group-option justone-group" name="groupoptions[]" value='-1'>{{# str }} withoutGroup, format_iena {{/ str}}</label>
+			</li>
+				<optgroup label="Mes groupes">
+				</optgroup>
+				<ul class="iena-dynamic-options">
+					{{#current_user_groups}}
+	  					<li><label class="checkbox"><input type="checkbox" name="groupoptions[]" value={{id}} class="group-option justone-group">{{name}}</label></li>
+						
+	  				{{/current_user_groups}}
+				</ul>
+				
+
+				<optgroup label="Autres groupes">
+					
+				</optgroup>
+				{{#othergroups}}
+						<li><label class="checkbox"><input type="checkbox" name="groupoptions[]" value={{id}} class="group-option justone-group">{{name}}</label></li>
+
+					{{/othergroups}}
+			</ul>
+		</div>
+		
 
-			<optgroup label="Mes groupes">
-				{{#current_user_groups}}
-					<option {{selected}} value='{{id}}'>{{name}}</option>";
-				{{/current_user_groups}}
-			</optgroup>
-			
-			<optgroup label="Autres groupes">
-				{{#groups}}
-					<option {{selected}} value='{{id}}'>{{name}}</option>";
 
-				{{/groups}}
-			</optgroup>
-			
-			
-			
-		</select>
 	</div>
 
-	<label class="sr-only" for="filter-select">Filtre %</label>
+	<label class="sr-only" for="filter-select">{{# str }} filter, format_iena {{/ str}} %</label>
 	<div class="input-group">
 		<div class="input-group-prepend">
-			<div class="input-group-text">% achèvement</div>
+			<div class="input-group-text">% {{# str }} completion, format_iena {{/ str}}</div>
 		</div>
 		<select class="custom-select mr-sm-2" id="symbol-select" name="filter">
 			
@@ -115,10 +136,10 @@
 	</div>
 </form>
 {{#msg_success}}
-	<div class="alert alert-success iena-message">Message(s) envoyé(s)</div>
+	<div class="alert alert-success iena-message">{{# str }} messagesSent, format_iena {{/ str}}</div>
 {{/msg_success}}
 {{#msg_failure}}
-	<div class="alert alert-danger  iena-message">Messages non envoyés</div>
+	<div class="alert alert-danger  iena-message">{{# str }} messagesNotSent, format_iena {{/ str}}</div>
 {{/msg_failure}}
 <div id="caption-iena"><h5>{{# str }} caption, format_iena {{/ str}}</h5>
 	<div class="caption-wrapper">
@@ -135,6 +156,9 @@
 require(['format_iena/suivi', 'core/templates'], function(module) {
     module.registerFilters();
    	module.registerSubmit({{{ data }}});
+   	module.registerSelectAllActivitiesFilter();
+   	module.registerSelectAllGroupsFilter();
+   	module.initTable();
 });
 {{/js}}
 </div>
diff --git a/tests/my_test.php b/tests/my_test.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a209214ab52464063d018f49fa87a2c967a8744
--- /dev/null
+++ b/tests/my_test.php
@@ -0,0 +1,238 @@
+<?php
+
+
+global $CFG;
+require_once($CFG->dirroot. '\course\format\iena\classes\form\edittable_form.php');
+
+
+
+class my_test extends \advanced_testcase {
+
+    public function test_get_array_options(){
+        global $DB, $CFG;
+        $this->resetAfterTest(true);
+        $olddebug = $CFG->debug;
+        $CFG->debug = 0;
+        $generator = $this->getDataGenerator();
+        $course1 = $generator->create_course();
+        $course2 = $generator->create_course();
+        $data=[
+            "option1"=>[
+                "option"=>"display_groups",
+                "value"=>"1",
+                "courseid"=>$course1->id,
+                "userid"=>"1",
+            ],
+            "option2"=>[
+                "option"=>"display_custom",
+                "value"=>"1",
+                "courseid"=>$course1->id,
+                "userid"=>"1",
+            ],
+            "option3"=>[
+                "option"=>"display_details",
+                "value"=>"1",
+                "courseid"=>$course1->id,
+                "userid"=>"1",
+            ],
+            "option4"=>[
+                "option"=>"display_status",
+                "value"=>"1",
+                "courseid"=>$course2->id,
+                "userid"=>"1",
+            ]
+        ];
+         // Create a set of options for the table.
+         
+        foreach($data as $x => $i){
+            $obj=new \format_iena\output\course_format_iena_table_option(null, 0, $i["courseid"], $i["userid"]);
+            $arrayoptionsid=$obj->save_property($i["option"], $i["value"]);
+        }
+        $arrayoptions=$obj->get_options_by_course_id($course1->id);
+        
+        $this->assertCount(3, $arrayoptions);
+        $arrayoptions2=$obj->get_options_by_course_id($course2->id);
+        
+        $this->assertCount(1, $arrayoptions2);
+        
+        $CFG->debug = $olddebug;
+
+        
+
+    }
+
+
+	public function test_create_option() {
+        global $DB, $CFG;
+        $this->resetAfterTest(true);
+
+        $olddebug = $CFG->debug;
+        $CFG->debug = 0;
+
+
+        $data=[
+            "option"=>\format_iena\output\course_format_iena_table_option::DISPLAY_GROUPS,
+            "value"=>"1",
+            "courseid"=>"1",
+            "userid"=>"1",
+        ];
+         // Create a set of options for the table.
+        $obj=new \format_iena\output\course_format_iena_table_option($data["option"], $data["value"], $data["courseid"], $data["userid"]);
+        
+
+        $arrayoptionsid=$obj->create_array_option();
+        // Check the preset data.
+        
+        $arrayoptions = $DB->get_record('format_iena_options', ['id' => $arrayoptionsid]);
+
+      
+        $this->assertEquals($data["option"], $arrayoptions->optionname);
+        $this->assertEquals($data["value"], $arrayoptions->optionvalue);
+        $this->assertEquals($data["courseid"], $arrayoptions->courseid);
+        $this->assertEquals($data["userid"], $arrayoptions->userid);
+
+    
+        $CFG->debug = $olddebug;
+    }
+
+    public function test_update_option(){
+
+        global $DB, $CFG;
+        $this->resetAfterTest(true);
+
+        $olddebug = $CFG->debug;
+        $CFG->debug = 0;
+        $obj=new \format_iena\output\course_format_iena_table_option();
+        $data=[
+            "option"=>$obj::DISPLAY_GROUPS,
+            "value"=>"1",
+            "courseid"=>"1",
+            "userid"=>"1",
+        ];
+         // Create a set of options for the table.
+       
+        
+        $obj->setCourseId($data["courseid"]);
+        $obj->setUserId($data["userid"]);
+        $arrayoptionsid=$obj->save_property($data["option"], $data["value"]);
+        // Check the preset data.
+        
+        $arrayoptions = $DB->get_record('format_iena_options', ['id' => $arrayoptionsid]);
+        $this->assertEquals($data["option"], $arrayoptions->optionname);
+        $this->assertEquals($data["value"], $arrayoptions->optionvalue);
+        $this->assertEquals($data["courseid"], $arrayoptions->courseid);
+        $this->assertEquals($data["userid"], $arrayoptions->userid);
+
+        $this->assertNull($arrayoptions->timemodified);
+
+        $arrayoptionsid2=$obj->save_property($data["option"], 0, $arrayoptionsid);
+  
+        $arrayoptionsupdated = $DB->get_record('format_iena_options', ['id' => $arrayoptionsid]);
+
+        $this->assertEquals($data["option"], $arrayoptionsupdated->optionname);
+        $this->assertEquals(0, $arrayoptionsupdated->optionvalue);
+        $this->assertEquals($data["courseid"], $arrayoptionsupdated->courseid);
+        $this->assertEquals($data["userid"], $arrayoptionsupdated->userid);
+
+        $this->assertEquals($arrayoptions->timecreated, $arrayoptionsupdated->timecreated);
+        $this->assertNotNull($arrayoptionsupdated->timemodified);
+
+        $CFG->debug = $olddebug;
+    	
+    }
+
+    public function test_uncheck_option(){
+
+        global $DB, $CFG;
+        $this->resetAfterTest(true);
+
+        $olddebug = $CFG->debug;
+        $CFG->debug = 0;
+        $obj=new \format_iena\output\course_format_iena_table_option();
+        $data=[
+            "option"=>$obj::DISPLAY_GROUPS,
+            "value"=>"1",
+            "courseid"=>"1",
+            "userid"=>"1",
+        ];
+        $data2=[
+            "option"=>"display_custom",
+            "value"=>"1",
+            "courseid"=>"1",
+            "userid"=>"1",
+        ];
+         // Create a set of options for the table.
+       
+        
+        $obj->setCourseId($data["courseid"]);
+        $obj->setUserId($data["userid"]);
+        $idoptiongroup=$obj->save_property($data["option"], $data["value"]);
+        // Check the preset data.
+        
+        $idoptioncustom=$obj->save_property($data2["option"], $data2["value"]);
+       // fwrite(STDERR, print_r($arrayoptionsid2, TRUE));
+       $arrayrequest=$DB->get_records('format_iena_options',["courseid"=>1]);
+        $arrayoptions=$obj->get_request_options();
+
+        $this->assertCount(2, $arrayrequest);
+        $this->assertEquals($obj->listoptions[$obj::DISPLAY_GROUPS]["id"], $idoptiongroup);
+        $this->assertEquals($obj->listoptions[$obj::DISPLAY_CUSTOM]["id"], $idoptioncustom);
+        
+
+
+        $listoptions=$obj->get_list_options();
+        $arraycustomform=$obj->listoptions;
+        $arraycustomform["courseid"]=1;
+        
+        // Instantiate a form to submit.
+        $values=[
+            $obj::DISPLAY_GROUPS=>1,
+            $obj::DISPLAY_CUSTOM=>0
+        ];
+
+        // Fetch the data and then mock the submission of that data.
+        
+        edittable_form::mock_submit($values);
+
+        $mform= new edittable_form(null, $arraycustomform);
+        $this->assertTrue($mform->is_validated());
+        // The `get_data()` function will return the validated data, plus any defaults.
+        $actualfromform = $mform->get_data();
+        $obj->check_options_state($actualfromform);
+        $arrayrequest=$DB->get_records('format_iena_options',["courseid"=>1, "optionvalue"=>1]);
+        $arrayrequestall=$DB->get_records('format_iena_options',["courseid"=>1]);
+
+        $this->assertCount(1, $arrayrequest);
+        $this->assertEquals($arrayrequest[$idoptiongroup]->optionname, $obj::DISPLAY_GROUPS);
+        $this->assertCount(2, $arrayrequestall);
+        $this->assertEquals($arrayrequestall[$idoptioncustom]->optionname, $obj::DISPLAY_CUSTOM);
+        $this->assertEquals($arrayrequestall[$idoptioncustom]->optionvalue, $values[$obj::DISPLAY_CUSTOM]);
+        $CFG->debug = $olddebug;
+        
+    }
+
+    /*public function create_options_provider(): array {
+        return [
+            'Full preset' => [
+                'name' => 'Full',
+                'comments' => null,
+                'author' => null,
+                'applypreset' => false,
+                'iscore' => manager::FULL_PRESET,
+                'iscoreresult' => manager::FULL_PRESET,
+            ],
+            'Invalid iscore' => [
+                'name' => 'Invalid iscore value',
+                'comments' => null,
+                'author' => null,
+                'applypreset' => false,
+                'iscore' => -1,
+                'iscoreresult' => manager::NONCORE_PRESET,
+            ],
+        ];
+    }*/
+
+
+
+
+}
\ No newline at end of file
diff --git a/version.php b/version.php
index 517393a120a4a059016322419adfcf6d70898631..09ca18f8efb282537457af51973fd814ca17f752 100644
--- a/version.php
+++ b/version.php
@@ -27,7 +27,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version = 2023000001;
+$plugin->version = 2024101500;
 $plugin->requires = 2014111000;
 $plugin->component = 'format_iena';
 $plugin->release = "1.0";