Commit c121cdad authored by Alberto Jiménez's avatar Alberto Jiménez

Update directory

parent 701e831d
# **NOTE MY PROGRESS para LMS Moodle**
NMP Moodle es un plugin de Moodle para profesores y estudiantes que tiene como objetivo apoyar la capacidad de autorregulación de los estudiantes. Concretamente, ayuda a desarrollar competencias relacionadas con el trabajo autónomo en entornos de aprendizaje en línea e híbridos.
## # Instalación
1. Descarga o clona el proyecto
2. Mueve la carpeta **student_reports** dentro de la carpeta **local** ubicada en la raíz de moodle
3. Ingresar en moodle como administrador
4. Comprueba que esté **student reports** cuando se listan los plugins que requieren atención
5. Haz clic en“*Actualizar la base de datos de moodle ahora*”para iniciar la instalación
6. Purga las cachés de la plataforma
## # Requisitos
- Moodle > 3.X
## | Librerías y frameworks empleados
A continuación se detallan las diferentes librerías Y frameworks utilizados en el desarrollo del plugin.
| **Nombre** | **Descripción** | **Versión** |
| -- | -- | -- |
| AlertifyJS | Cuadros de diálogo y notificaciones del navegador | 1.11.4 |
| Axios | Genera solicitudes HTTP | 0.19.0 |
| Chart JS | Gráficos animados e interactivos | 2.7.2 |
| Vuejs Datepicker | Selector de fechas para vuejs | 1.6.2 |
| Vue Masonry Css | Diseño de cuadrícula basada en el espacio vertical disponible | 1.0.3|
| Vue Masonry | Diseño de cuadrícula basada en el espacio vertical disponible (*Dependencia de Vue Masonry Css*) | 4.2.2 |
| Moment.js | Manipulación de fechas | 2.24.0 |
| Vue Draggable | Arrastrar y soltar elementos para vuejs | 2.23.2 |
| Sortable | Permite ordenar los elementos arrastrados y soltados (*Dependencia de Vue Draggable*) | 1.10.0-rc3 |
| Vue JS | Marco de javascript progresivo | 2.6.10 |
| Vue Quill | Editor de texto enriquecido | 1.5.1 |
| Quill Editor | Editor de texto enriquecido (*Dependencia de Vue Quill*) | 1.3.4 |
| Vuetify | Librería de componentes visuales para vuejs | 2.0.5 |
## | Estructura de carpetas
Se da por entendido que al estar acá, usted cuenta con el conocimiento técnico suficiente para no tener que explicar en detalle qué es cada fichero, por lo cual nos limitaremos a explicar solo lo importante.
#### > RAIZ
Los ficheros de reportes son un intermediario entre la obtención de datos mediante las clases y el llamado a los ficheros que renderizan (Template / Módulos Javascript).
Los ficheros generales son miscelánea de la estructura de un plugin en moodle
#####Ficheros de reportes
activities_performed_teacher.php
activities_performed.php
metareflexion.php
notes.php
setweeks.php
time_visualizations.php
time_worked_session_report.php
#####Ficheros generales
version.php: Contiene la configuración básica necesaria para el funcionamiento del plugin.
lib.php: Librería global de moodle, los cambios que se apliquen acá estarán disponible en toda la plataforma. Cuidado con los alcances de nombres!
locallib.php: Librería local del plugin.
ajax.php: Funciones que dan respuesta a las peticiones ajax realizadas desde el plugin.
styles.css: Estilos globales para el plugin.
#### > AMD
Los ficheros javascript correspondientes a la programación del plugin, conversión de módulos estándar a AMD y la configuración de SHIM se encuentra acá.
La definición de módulos o incorporación de librerías debe hacerse mediante *RequireJS* y sus respectivas normas.
###### Sub-directorios
**- build**: Archivos de amd/src minificados, son los que carga moodle cuando se encuentra en modo“Producción”.
**- src**: Archivos sin minificar, estos serán los cargados por moodle cuando esté activado el modo “Desarrollador”.
------------
#### > CLASSES
Clases utilizadas para la manipulación de datos, las clases son cargadas automáticamente mediante autoload por moodle.
###### Ficheros
**- configweeks.php**: Clase encargada de gestionar la configuración de las semanas.
** - libtrait.php**: Trait utilizado como libreria, contiene funciones de reutilización para las diferentes clases. (Para utilizar el trait se necesita que la clase que lo “usa” posea las propiedades $course y $user con su respectivo objeto).
** - metareflexion.php**: Clase encargada de gestionar las planificaciones de metareflexión.
** - notes.php**: Clase encargada de gestionar las notas.
** - report.php**: Clase utilizada como núcleo para la obtención de reportes.
** - resourcetype.php**: Clase que permite obtener el tipo de recurso dado su mimetype.
** - srlog.php**: Clase que permite gestionar los logs
**student.php**: Clase que configura los reportes para estudiantes y cuenta con reportes exclusivos de estudiantes, extiende de report.php
**teacher.php**: Clase que configura los reportes para profesor y cuenta con reportes exclusivos de profesor, extiende de report.php
------------
#### > CSS
Hojas de estilo correspondientes a las librerías externas.
------------
#### > DB
Ficheros relacionados a la base de datos y definición de nuevas capabilities .
###### Ficheros
** - access.php**: Contiene las nuevas capabilities utilizadas por el plugin.
** - install.php**: Contiene el poblado inicial de las tablas (Seeder).
** - install.xml**: Contiene la estructura de la base de datos, esta estructura debe crearse -*preferentemente*- mediante el editor XMLDB de moodle
------------
#### > DOWNLOADS
Almacena los ficheros de logs que se han generado y los pone a disposición para la descarga.
------------
#### > FONTS
Fuentes requeridas por librerías de terceros
------------
#### > JS
Contiene los diferentes ficheros javascript de librerías que no son módulos AMD.
La carga de estos ficheros puede encontrarse en la configuración de SHIM, dentro de la carpeta amd. La conversión a módulo amd corresponde al fichero javascript que posee el mismo nombre.
------------
#### > LANG
Directorio que contiene los paquetes de idiomas.
------------
#### > TEMPLATES
Contiene la estructura visual de cada página del plugin.
Es importante mencionar que estamos trabajando con vuejs y no con mustache, por lo cual se ha configurado la interpolación de vue como “[[ ]]“.
# **NOTE MY PROGRESS pour LMS Moodle**
NMP Moodle est un plugin Moodle pour les enseignants et les étudiants qui vise à soutenir la capacité d'autorégulation des étudiants. Plus précisément, il aide à développer les compétences liées au travail autonome dans des environnements d'apprentissage en ligne et hybrides.
## # Installation
1. Télécharger ou cloner le projet
2. Déplacer le dossier **student_reports** dans le dossier **local** situé à la racine de moodle
3. Connectez-vous à moodle en tant qu'administrateur
4. Vérifiez que vous êtes bien un **student_reportst** lorsque vous énumérez les plugins qui nécessitent une attention particulière
5. Cliquez sur "*Mettre à jour la base de données moodle maintenant*" pour lancer l'installation
6. Purger les caches de la plate-forme
## # Conditions d'installation
- Moodle > 3.X
## | Bibliothèques etframeworks utilisés
Vous trouverez ci-dessous les différentes bibliothèques et frameworks utilisés dans le développement du plugin.
| **Nom** | **Description** | **Version** |
| -- | -- | -- |
| AlertifyJS | Boîtes de dialogue et notifications du navigateur | 1.11.4 |
| Axios | Génère des requêtes HTTP | 0.19.0 |
| Chart JS | Graphiques animés et interactifs | 2.7.2 |
| Vuejs Datepicker | Sélecteur de date pour vuejs | 1.6.2 |
| Vue Masonry Css | Conception de la grille en fonction de l'espace vertical disponible | 1.0.3|
| Vue Masonry | Conception de la grille en fonction de l'espace vertical disponible (* Dépendance de Vue Masonry Css*) | 4.2.2 |
| Moment.js | Manipulation des dates | 2.24.0 |
| Vue Draggable | Déplacer des objets vuejs | 2.23.2 |
| Sortable | Permet de trier les objets glissés et déposés (*Dépendance de Vue Draggable*) | 1.10.0-rc3 |
| Vue JS | Cadre javascript progressif | 2.6.10 |
| Vue Quill | Éditeur de texte enrichi | 1.5.1 |
| Quill Editor | Éditeur de texte enrichi (*Dépendance de Vue Quill*) | 1.3.4 |
| Vuetify | Bibliothèque de composants visuels pour vuesjs | 2.0.5 |
## | Structure des dossiers
Il est entendu qu'en étant ici, vous avez suffisamment de connaissances techniques pour ne pas avoir à expliquer en détail ce qu'est chaque dossier, nous nous limiterons donc à expliquer uniquement ce qui est important.
#### > RACINE
Les fichiers de rapport sont un intermédiaire entre l'obtention des données par les classes et l'appel des fichiers qu'ils pour le "render" (modules Template / Javascript).
Les fichiers généraux sont divers de la structure d'un plugin dans moodle
#####Fichiers de rapport
activities_performed_teacher.php
activities_performed.php
metareflexion.php
notes.php
setweeks.php
time_visualizations.php
time_worked_session_report.php
#####Fichiers généraux
version.php: Contient la configuration de base nécessaire au fonctionnement du plugin.
lib.php : la bibliothèque globale de moodle, les changements appliqués ici seront disponibles dans toute la plateforme. Attention aux portées de noms !
locallib.php : Bibliothèque locale du plugin.
ajax.php : Fonctions qui donnent une réponse aux requêtes ajax faites à partir du plugin.
styles.css : Styles globaux pour le plugin.
#### > AMD
Les fichiers javascript correspondant à la programmation du plugin, à la conversion des modules standard en AMD et à la configuration de SHIM se trouvent ici.
La définition des modules ou l'incorporation des bibliothèques doit se faire par le biais de *RequireJS* et de leurs normes respectives.
###### Sub-directorios
**- build** : Fichiers amd/src minimisés, sont ceux qui chargent moodle en mode "Production".
**- src** : Fichiers non minimisés, ce sont ceux qui sont chargés par moodle en mode "Développeur".
------------
#### > CLASSES
Les classes utilisées pour la manipulation des données, les classes sont automatiquement chargées via l'autochargement par moodle.
###### Fichiers
**- configweeks.php** : Classe chargée de gérer la configuration des semaines.
** - libtrait.php** : Trait utilisé comme bibliothèque, il contient des fonctions de réutilisation pour les différentes classes (Pour utiliser le trait, il est nécessaire que la classe qui l'"utilise" ait les propriétés $course et $user avec son objet respectif).
** - metareflexion.php** : Classe chargée de la gestion des plans de méta-réflexion.
** - notes.php** : Classe chargée de la gestion des notes.
** - report.php** : Classe utilisée comme noyau pour obtenir des rapports.
** - resourcetype.php** : Classe qui permet d'obtenir le type de ressource étant donné son mimetype.
** - srlog.php** : Classe utilisée pour gérer les logs
**student.php** : Classe qui configure des rapports pour les étudiants et qui a des rapports exclusifs pour les étudiants, s'étend de report.php
**teacher.php** : Classe qui configure les rapports des enseignants et qui dispose de rapports exclusifs des enseignants, s'étend de report.php
------------
#### > CSS
Feuilles de style correspondant aux librairies externes.
------------
#### > DB
Dossiers relatifs à la base de données et à la définition des nouvelles capacités.
###### Fichiers
** - access.php** : Contient les nouvelles capacités utilisées par le plugin.
** - install.php** : Contient la population initiale des tables (Seeder).
** - install.xml** : Contient la structure de la base de données, cette structure doit être créée -*de préférence*- par l'éditeur XMLDB de moodle
------------
#### > DOWNLOADS
Il stocke les fichiers journaux qui ont été générés et les met à disposition pour le téléchargement.
------------
#### > FONTS
Sources requises par les bibliothèques de tierces
------------
#### > JS
Il contient les différents fichiers javascript des bibliothèques qui ne sont pas des modules AMD.
Le chargement de ces fichiers se trouve dans la configuration SHIM, dans le dossier amd. La conversion en module amd correspond au fichier javascript qui porte le même nom.
------------
#### > LANG
Répertoire contenant les packs de langues. Le fichier terminé en FR contient la traduction française du module.
------------
#### > MODÈLES
Il contient la structure visuelle de chaque page du plugin.
Il est important de mentionner que nous travaillons avec des vuejs et non ave moustache, donc l'interpolation des vues a été réglée sur "[ ]".
<?php
global $COURSE, $USER;
require_once('locallib.php');
$courseid = required_param('courseid', PARAM_INT);
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$context = context_course::instance($course->id);
require_capability('local/student_reports:usepluggin', $context);
require_capability('local/student_reports:view_report_as_student', $context);
require_capability('local/student_reports:activities_performed', $context);
if(is_siteadmin()){
print_error(get_string("only_student","local_student_reports"));
}
$url = '/local/student_reports/activities_performed.php';
local_sr_set_page($course,$url);
local_student_reports_srlog::create("activities_performed","view", $USER->id, $COURSE->id);
$reports = new local_student_reports_student($COURSE->id, $USER->id);
$configweeks = new local_student_reports_configweeks($COURSE, $USER);
if(!$configweeks->is_set()){
$message = get_string("weeks_not_config", "local_student_reports");
print_error($message);
}
$content = [
'strings' =>[
"title" => get_string("ap_title","local_student_reports"),
"description_student" => get_string("ap_description_student","local_student_reports"),
"description_teacher" => get_string("ap_description_teacher","local_student_reports"),
"tv_resource_document" => get_string("tv_resource_document","local_student_reports"),
"tv_resource_image" => get_string("tv_resource_image","local_student_reports"),
"tv_resource_audio" => get_string("tv_resource_audio","local_student_reports"),
"tv_resource_video" => get_string("tv_resource_video","local_student_reports"),
"tv_resource_file" => get_string("tv_resource_file","local_student_reports"),
"tv_resource_script" => get_string("tv_resource_script","local_student_reports"),
"tv_resource_text" => get_string("tv_resource_text","local_student_reports"),
"tv_resource_download" => get_string("tv_resource_download","local_student_reports"),
"tv_assign" => get_string("tv_assign","local_student_reports"),
"tv_assignment" => get_string("tv_assignment","local_student_reports"),
"tv_book" => get_string("tv_book","local_student_reports"),
"tv_choice" => get_string("tv_choice","local_student_reports"),
"tv_feedback" => get_string("tv_feedback","local_student_reports"),
"tv_folder" => get_string("tv_folder","local_student_reports"),
"tv_forum" => get_string("tv_forum","local_student_reports"),
"tv_glossary" => get_string("tv_glossary","local_student_reports"),
"tv_label" => get_string("tv_label","local_student_reports"),
"tv_lesson" => get_string("tv_lesson","local_student_reports"),
"tv_page" => get_string("tv_page","local_student_reports"),
"tv_quiz" => get_string("tv_quiz","local_student_reports"),
"tv_survey" => get_string("tv_survey","local_student_reports"),
"tv_lti" => get_string("tv_lti","local_student_reports"),
"axis_x" => get_string("ap_axis_x","local_student_reports"),
"axis_y" => get_string("ap_axis_y","local_student_reports"),
"progress" => get_string("ap_progress","local_student_reports"),
"tv_other" => get_string("tv_other","local_student_reports"),
"week" => get_string("ap_week","local_student_reports"),
"to" => get_string("ap_to","local_student_reports"),
"graph_generating" => get_string("graph_generating","local_student_reports"),
"activities" => get_string("ap_activities","local_student_reports"),
"api_error_network" => get_string("api_error_network","local_student_reports"),
"pagination_title" => get_string("pagination_title","local_student_reports"),
"helplabel" => get_string("helplabel","local_student_reports"),
"exitbutton" => get_string("exitbutton","local_student_reports"),
],
'courseid' => $COURSE->id,
'userid' => $USER->id,
'module_groups' => $reports->get_modules_completion(),
'pages' => $configweeks->get_weeks_paginator(),
'render_has' => $reports->render_has(),
'groups' => local_sr_get_groups($course, $USER),
];
$PAGE->requires->js_call_amd('local_student_reports/activities_performed','init', ['content' => $content]);
echo $OUTPUT->header();
echo $OUTPUT->render_from_template('local_student_reports/activities_performed', ['content' => $content]);
echo $OUTPUT->footer();
\ No newline at end of file
<?php
global $COURSE, $USER;
require_once('locallib.php');
$courseid = required_param('courseid', PARAM_INT);
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$context = context_course::instance($course->id);
require_capability('local/student_reports:usepluggin', $context);
require_capability('local/student_reports:view_report_as_teacher', $context);
require_capability('local/student_reports:activities_performed_teacher', $context);
$url = '/local/student_reports/activities_performed_teacher.php';
local_sr_set_page($course,$url);
local_student_reports_srlog::create("activities_performed_teacher","view", $USER->id, $COURSE->id);
$configweeks = new local_student_reports_configweeks($COURSE, $USER);
if(!$configweeks->is_set()){
$message = get_string("weeks_not_config", "local_student_reports");
print_error($message);
}
$content = [
'strings' =>[
"title" => get_string("apt_title", "local_student_reports"),
"description" => get_string("apt_description", "local_student_reports"),
"axis_x" => get_string("apt_axis_x", "local_student_reports"),
"axis_y" => get_string("apt_axis_y", "local_student_reports"),
"visualizations_average" => get_string("apt_visualization_average", "local_student_reports"),
"interactions_average" => get_string("apt_interacctions_average", "local_student_reports"),
"tv_to" => get_string("ap_to","local_student_reports"),
"week" => get_string("ap_week","local_student_reports"),
"pagination_name" => get_string("pagination_component_name","local_student_reports"),
"pagination_separator" => get_string("pagination_component_to","local_student_reports"),
"api_error_network" => get_string("api_error_network","local_student_reports"),
"graph_generating" => get_string("graph_generating","local_student_reports"),
"thead_name" => get_string("apt_thead_name","local_student_reports"),
"thead_lastname" => get_string("apt_thead_lastname","local_student_reports"),
"thead_email" => get_string("apt_thead_email","local_student_reports"),
"thead_interactions" => get_string("apt_thead_interactions","local_student_reports"),
"thead_visualization" => get_string("apt_thead_visualization","local_student_reports"),
"helplabel" => get_string("helplabel","local_student_reports"),
"exitbutton" => get_string("exitbutton","local_student_reports"),
],
'courseid' => $COURSE->id,
'userid' => $USER->id,
'pages' => $configweeks->get_weeks_paginator(),
'course_modules' => [],
'groups' => local_sr_get_groups($course, $USER),
];
$PAGE->requires->js_call_amd('local_student_reports/activities_performed_teacher','init', ['content' => $content]);
echo $OUTPUT->header();
echo $OUTPUT->render_from_template('local_student_reports/activities_performed_teacher', ['content' => $content]);
echo $OUTPUT->footer();
\ No newline at end of file
This diff is collapsed.
define(["local_student_reports/vue",
"local_student_reports/vuetify",
"local_student_reports/axios",
"local_student_reports/chartcomponent",
"local_student_reports/pageheadercomponent",
"local_student_reports/paginationcomponent",
],
function(Vue, Vuetify, Axios, Chart, Pageheader, Pagination) {
"use strict";
function clone(obj){
return JSON.parse(JSON.stringify(obj))
}
function init(content) {
Vue.use(Vuetify)
Vue.component('pageheader', Pageheader)
Vue.component('pagination', Pagination)
Vue.component('chart', Chart)
new Vue({
delimiters: ["[[", "]]"],
el: "#activities_performed",
vuetify: new Vuetify(),
data: {
groups : content.groups,
strings : content.strings,
module_groups : content.module_groups,
loading : false,
pages : content.pages,
userid : content.userid,
courseid : content.courseid,
render_has : content.render_has,
errors : [],
chart_options: {
tooltips: {
mode: 'label',
callbacks: {
label: function(tooltipItem, data) {
return data.datasets[tooltipItem.datasetIndex].label + ": " + tooltipItem.yLabel;
}
}
},
scales: {
xAxes: [{
stacked: true,
barPercentage: .8,
gridLines: { display: false },
scaleLabel: {
display: true,
labelString: content.strings.axis_x,
fontSize: 18,
},
ticks: {
autoSkip: true,
stepSize: 1,
suggestedMin: 0,
suggestedMax: 5,
},
}],
yAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: content.strings.axis_y,
fontSize: 18,
},
ticks: {
autoSkip: true,
stepSize: 1,
suggestedMin: 0,
suggestedMax: 5,
callback: function(value) { return value; },
},
}],
},
legend: {display: true}
}
},
mounted(){
document.querySelector("#sr-loader").style.display = "none"
document.querySelector("#activities_performed").style.display = "block"
},
computed : {
progress(){
var count_all = 0
var count_finished = 0
Object.keys(this.module_groups).map( key => {
let group = this.module_groups[key]
count_all += group.count_all
count_finished += group.count_finished
})
let average = count_finished * 100 / count_all
average = Number.isNaN(average) ? 0 : average.toFixed(0)
return average
},
},
methods : {
get_chart_data(){
var finished = [];
var pending = [];
var resources = [];
Object.keys(this.module_groups).map( key => {
let group_name = this.translate_name(key, "tv_")
let group = this.module_groups[key]
resources.push(group_name)
finished.push(group.count_finished)
pending.push(group.count_pending)
})
var data = {
labels: resources,
datasets: [
{
label: 'Finalizados',
data: finished,
backgroundColor: "#82D620",
borderWidth : 1,
hoverBorderWidth: 0
},
{
label: 'Pendientes',
data: pending,
backgroundColor: "rgba(252, 78, 63, .8)",
borderWidth : 1,
hoverBorderWidth: 0
}
]
}
return data
},
translate_name(name, prefix){
var index_name = prefix + name
if(!(typeof(this.strings[index_name]) == "undefined")){
name = this.strings[index_name]
}
return name
},
update_module_groups(week){
var validresponse = false
this.errors = []
this.loading = true
var data = {
action : "activitiesperformed",
userid : this.userid,
courseid : this.courseid,
weekcode : week.weekcode,
}
Axios({
method:'get',
url: M.cfg.wwwroot + "/local/student_reports/ajax.php",
params : data,
}).then((response) => {
if(response.status == 200 && response.data.valid){
validresponse = true
this.module_groups = response.data.data.module_groups
this.loading = false
}else{
this.errors.push(this.strings.api_error_network)
this.loading = false
}
}).catch((e) => {
this.errors.push(this.strings.api_error_network)