Commit 0c3bc699 by Pablo Molina

Merge branch 'issue/236' into 'develop'

Solved #236
parents fa7af2e6 71361cbe
...@@ -26,11 +26,11 @@ ...@@ -26,11 +26,11 @@
"alert": "Alert", "alert": "Alert",
"all": "All", "all": "All",
"animation": "Animation", "animation": "Animation",
"April": "April", "April": "April",
"attributes_not_updated": "Changes not saved", "attributes_not_updated": "Changes not saved",
"attributes_updated": "Changes saved", "attributes_updated": "Changes saved",
"attributes_updating": "Saving...", "attributes_updating": "Saving...",
"August": "August", "August": "August",
"background": "Background", "background": "Background",
"beep": "Beep", "beep": "Beep",
"birthdate": "Birthdate", "birthdate": "Birthdate",
...@@ -84,6 +84,10 @@ ...@@ -84,6 +84,10 @@
"english": "English", "english": "English",
"enlarge": "Enlarge", "enlarge": "Enlarge",
"enormous": "Enormous", "enormous": "Enormous",
"error_downloading_supervisors": "Error downloading supervisors",
"error_downloading_offices": "Error downloading offices",
"error_only_support_images": "Only images are supported (JPG, PNG or GIF files)",
"error_loading_pictos": "Error loading pictos information",
"expand_navigation": "Expand navigation", "expand_navigation": "Expand navigation",
"expand_navigation": "Expand navigation", "expand_navigation": "Expand navigation",
"expression": "Expression:", "expression": "Expression:",
...@@ -106,9 +110,9 @@ ...@@ -106,9 +110,9 @@
"instructions": "Instructions", "instructions": "Instructions",
"invalid_fields": "Invalid values. Please, check fields introduced.", "invalid_fields": "Invalid values. Please, check fields introduced.",
"invisible": "Invisible. Clic for enable", "invisible": "Invisible. Clic for enable",
"January": "January", "January": "January",
"July": "July", "July": "July",
"June": "June", "June": "June",
"language": "Language", "language": "Language",
"large": "Large", "large": "Large",
"last_session": "Last session", "last_session": "Last session",
...@@ -123,10 +127,10 @@ ...@@ -123,10 +127,10 @@
"login_success": "Login succeed. Welcome {{name}}", "login_success": "Login succeed. Welcome {{name}}",
"logout": "Log Out", "logout": "Log Out",
"man": "Man", "man": "Man",
"March": "March", "March": "March",
"mark": "Mark", "mark": "Mark",
"max_licenses_reached": "Maximum number of licenses reached by the office", "max_licenses_reached": "Maximum number of licenses reached by the office",
"May": "May", "May": "May",
"method_name_duplicated": "template already exists.Please, change the name", "method_name_duplicated": "template already exists.Please, change the name",
"method_save": "Method saved as a new template", "method_save": "Method saved as a new template",
"methods": "Methods", "methods": "Methods",
...@@ -146,8 +150,8 @@ ...@@ -146,8 +150,8 @@
"num_peers": "Peers", "num_peers": "Peers",
"num_sessions_per_day_in": "Sessions per day in", "num_sessions_per_day_in": "Sessions per day in",
"num_sessions_per_month_in": "Sessions per months in", "num_sessions_per_month_in": "Sessions per months in",
"objetive": "Objetive", "objetive": "Objetive",
"October": "October", "October": "October",
"office": "Office", "office": "Office",
"office_added": "Office added", "office_added": "Office added",
"office_deleted": "Office deleted", "office_deleted": "Office deleted",
...@@ -156,7 +160,7 @@ ...@@ -156,7 +160,7 @@
"office_not_updated": "Office not updated", "office_not_updated": "Office not updated",
"office_updated": "Office updated", "office_updated": "Office updated",
"offices": "Offices", "offices": "Offices",
"own_labels": "Your labels", "own_labels": "Your labels",
"own_pictos": "Your pictograms", "own_pictos": "Your pictograms",
"pages": "Pages", "pages": "Pages",
"password": "Password", "password": "Password",
...@@ -196,7 +200,7 @@ ...@@ -196,7 +200,7 @@
"select_a_method": "-- Select a method --", "select_a_method": "-- Select a method --",
"select_method": "-- Select a method or create it --", "select_method": "-- Select a method or create it --",
"send": "Send", "send": "Send",
"September": "September", "September": "September",
"serial": "Serial number", "serial": "Serial number",
"serial_created": "Serial number {{serial}} created", "serial_created": "Serial number {{serial}} created",
"serial_list": "Free serial numbers", "serial_list": "Free serial numbers",
...@@ -213,7 +217,7 @@ ...@@ -213,7 +217,7 @@
"spanish": "Spanish", "spanish": "Spanish",
"started": "Started", "started": "Started",
"state": "State", "state": "State",
"state_broken": "Broken", "state_broken": "Broken",
"state_correct": "Correct", "state_correct": "Correct",
"state_demonstration": "Demonstration", "state_demonstration": "Demonstration",
"state_discarded": "Discarded", "state_discarded": "Discarded",
...@@ -229,9 +233,9 @@ ...@@ -229,9 +233,9 @@
"student_pictograms": "Student's pictograms", "student_pictograms": "Student's pictograms",
"student_updated": "Student updated", "student_updated": "Student updated",
"students": "Students", "students": "Students",
"sup_not_added": "Supervisor not added to the student.", "sup_not_added": "Supervisor not added to the student",
"sup_not_deleted": "The supervisor couldn't be deleted by the student", "sup_not_deleted": "The supervisor couldn't be deleted by the student",
"sup_not_found": "There is no supervisor account in Pictogram with this email.", "sup_not_found": "There is no supervisor account in Pictogram with this email",
"supervisor_added": "Supervisor added", "supervisor_added": "Supervisor added",
"supervisor_deleted": "Supervisor deleted", "supervisor_deleted": "Supervisor deleted",
"supervisor_not_added": "Supervisor not added", "supervisor_not_added": "Supervisor not added",
...@@ -258,8 +262,10 @@ ...@@ -258,8 +262,10 @@
"tries_per_instruction_method": "Tries per instruction of method", "tries_per_instruction_method": "Tries per instruction of method",
"tries_per_months": "Tries per months in", "tries_per_months": "Tries per months in",
"tries_results_instruction": "Tries results in instruction", "tries_results_instruction": "Tries results in instruction",
"tutor_added": "Tutor added to the student",
"tutor_deleted": "Tutor removed from the student",
"tutor_not_added": "Tutor not added to the student.", "tutor_not_added": "Tutor not added to the student.",
"tutor_not_deleted": "The tutor couldn't be deleted by the student", "tutor_not_deleted": "Tutor couldn't be removed from the student",
"tutor_not_found": "There is no tutor account in Pictogram with this email.", "tutor_not_found": "There is no tutor account in Pictogram with this email.",
"tutors": "Parents or tutors", "tutors": "Parents or tutors",
"unlink": "Unlink", "unlink": "Unlink",
......
...@@ -26,16 +26,16 @@ ...@@ -26,16 +26,16 @@
"alert": "Alerta", "alert": "Alerta",
"all": "Todos", "all": "Todos",
"animation": "Animación", "animation": "Animación",
"April": "Abril", "April": "Abril",
"attributes_not_updated": "Cambios no guardados", "attributes_not_updated": "Cambios no guardados",
"attributes_updated": "Cambios guardados", "attributes_updated": "Cambios guardados",
"attributes_updating": "Guardando...", "attributes_updating": "Guardando...",
"August": "Agosto", "August": "Agosto",
"background": "Fondo", "background": "Fondo",
"beep": "Pitido", "beep": "Pitido",
"birthdate": "Fecha de nacimiento", "birthdate": "Fecha de nacimiento",
"cancel": "Cancelar", "cancel": "Cancelar",
"cannot_delete_method": "No se pudo eliminar el método, tal vez porque existen sesiones asociadas.", "cannot_delete_method": "No se pudo eliminar el método, tal vez porque existen sesiones asociadas.",
"categories": "Categorías", "categories": "Categorías",
"category_pictograms": "Pictogramas de la categoría", "category_pictograms": "Pictogramas de la categoría",
"change_password": "Cambiar contraseña", "change_password": "Cambiar contraseña",
...@@ -87,6 +87,10 @@ ...@@ -87,6 +87,10 @@
"expand_navigation": "Desplegar navegación", "expand_navigation": "Desplegar navegación",
"expand_navigation": "Desplegar navegación", "expand_navigation": "Desplegar navegación",
"expression": "Expresión:", "expression": "Expresión:",
"error_downloading_supervisors": "Error al descargar los supervisores",
"error_downloading_offices": "Error al descargar las oficinas",
"error_only_support_images": "Sólo se soportan imágenes (ficheros JPG, PNG o GIF)",
"error_loading_pictos": "Error cargando información de los pictos",
"February": "Febrero", "February": "Febrero",
"feedback_picto": "Feedback al colocar un pictograma", "feedback_picto": "Feedback al colocar un pictograma",
"filter": "Filtrar", "filter": "Filtrar",
...@@ -106,9 +110,9 @@ ...@@ -106,9 +110,9 @@
"instructions": "Instrucciones", "instructions": "Instrucciones",
"invalid_fields": "Valores inválidos. Compruebe los datos introducidos.", "invalid_fields": "Valores inválidos. Compruebe los datos introducidos.",
"invisible": "Invisible. Clic para activar", "invisible": "Invisible. Clic para activar",
"January": "Enero", "January": "Enero",
"July": "Julio", "July": "Julio",
"June": "Junio", "June": "Junio",
"language": "Idioma", "language": "Idioma",
"large": "Grande", "large": "Grande",
"last_session": "Última sesión", "last_session": "Última sesión",
...@@ -123,10 +127,10 @@ ...@@ -123,10 +127,10 @@
"login_success": "Login correcto. Bienvenido {{name}}", "login_success": "Login correcto. Bienvenido {{name}}",
"logout": "Salir", "logout": "Salir",
"man": "Hombre", "man": "Hombre",
"March": "Marzo", "March": "Marzo",
"mark": "Marcar", "mark": "Marcar",
"max_licenses_reached": "Número de licencias máximo alcanzado por la oficina", "max_licenses_reached": "Número de licencias máximo alcanzado por la oficina",
"May": "Mayo", "May": "Mayo",
"method_name_duplicated": "plantilla ya existe. Por favor, cambie el nombre", "method_name_duplicated": "plantilla ya existe. Por favor, cambie el nombre",
"method_save": "Método guardado como nueva plantilla", "method_save": "Método guardado como nueva plantilla",
"methods": "Métodos", "methods": "Métodos",
...@@ -146,8 +150,8 @@ ...@@ -146,8 +150,8 @@
"num_peers": "Conectados", "num_peers": "Conectados",
"num_sessions_per_day_in": "Número de sesiones por día en", "num_sessions_per_day_in": "Número de sesiones por día en",
"num_sessions_per_month_in": "Número de sesiones por meses en", "num_sessions_per_month_in": "Número de sesiones por meses en",
"objetive": "Objetivo", "objetive": "Objetivo",
"October": "Octubre", "October": "Octubre",
"office": "Gabinete", "office": "Gabinete",
"office_added": "Gabinete añadido", "office_added": "Gabinete añadido",
"office_deleted": "Gabinete eliminado", "office_deleted": "Gabinete eliminado",
...@@ -156,8 +160,8 @@ ...@@ -156,8 +160,8 @@
"office_not_updated": "El gabinete no se ha podido actualizar", "office_not_updated": "El gabinete no se ha podido actualizar",
"office_updated": "Gabinete actualizado", "office_updated": "Gabinete actualizado",
"offices": "Gabinetes", "offices": "Gabinetes",
"own_labels": "Propias", "own_labels": "Propias",
"own_pictos": "Propios", "own_pictos": "Propios",
"pages": "Páginas", "pages": "Páginas",
"password": "Contraseña", "password": "Contraseña",
"password_confirm": "Repita la contraseña", "password_confirm": "Repita la contraseña",
...@@ -196,7 +200,7 @@ ...@@ -196,7 +200,7 @@
"select_a_method": "-- Selecciona un método --", "select_a_method": "-- Selecciona un método --",
"select_method": "-- Selecciona un método o créalo --", "select_method": "-- Selecciona un método o créalo --",
"send": "Enviar", "send": "Enviar",
"September": "Septiembre", "September": "Septiembre",
"serial": "Número de serie", "serial": "Número de serie",
"serial_created": "Número de serie {{serial}} creado", "serial_created": "Número de serie {{serial}} creado",
"serial_list": "Números de serie libres", "serial_list": "Números de serie libres",
...@@ -258,9 +262,11 @@ ...@@ -258,9 +262,11 @@
"tries_per_instruction_method": "Ensayos por instrucción del método", "tries_per_instruction_method": "Ensayos por instrucción del método",
"tries_per_months": "Número de ensayos por meses en", "tries_per_months": "Número de ensayos por meses en",
"tries_results_instruction": "Resultados ensayos en instrucción", "tries_results_instruction": "Resultados ensayos en instrucción",
"tutor_not_added": "El tutor no se ha podido añadir al estudiante.", "tutor_added": "Tutor añadido al estudiante",
"tutor_not_deleted": "El tutor no se ha podido desvincular del alumno.", "tutor_deleted": "Tutor desvinculado del estudiante",
"tutor_not_found": "No hay ningún tutor en Pictoram con ese correo electrónico.", "tutor_not_added": "El tutor no se ha podido añadir al estudiante",
"tutor_not_deleted": "El tutor no se ha podido desvincular del alumno",
"tutor_not_found": "No hay ningún tutor en Pictoram con ese correo electrónico",
"tutors": "Padres o tutores", "tutors": "Padres o tutores",
"undefined": "Sin definir", "undefined": "Sin definir",
"unlink": "Desvincular", "unlink": "Desvincular",
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
<body ng-controller="MainCtrl"> <body ng-controller="MainCtrl">
<!-- <div ng-view></div> --> <!-- <div ng-view></div> -->
<toast></toast>
<div ui-view></div> <div ui-view></div>
<!-- Librería jQuery requerida por los plugins de JavaScript <!-- Librería jQuery requerida por los plugins de JavaScript
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
//-------------------------- //--------------------------
// Admin Supervisors Controller // Admin Supervisors Controller
//-------------------------- //--------------------------
dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisorsCtrl($scope, $window, $http, config) { dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisorsCtrl($scope, $window, $http, config, $translate, ngToast) {
// The last parameter, config, is injected from config.js (defined in dashboardConfig module) // The last parameter, config, is injected from config.js (defined in dashboardConfig module)
// Don't show the message at the begining // Don't show the message at the begining
...@@ -25,26 +25,24 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor ...@@ -25,26 +25,24 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor
$http $http
.get(config.backend+'/sup') .get(config.backend+'/sup')
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
// Add to list
$scope.supervisors = data; $scope.supervisors = data;
console.log("Supervisors listed");
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error); $translate('error_downloading_supervisors').then(function (translation) {
ngToast.danger({ content: translation });
});
}); });
// List of offices (for the select form) // List of offices (for the select form)
$http $http
.get(config.backend+'/office/get_all') .get(config.backend+'/office/get_all')
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
// Add to list
$scope.offices = data; $scope.offices = data;
console.log("Offices listed");
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error); $translate('error_downloading_offices').then(function (translation) {
ngToast.danger({ content: translation });
});
}); });
// Reset form Supervisor // Reset form Supervisor
...@@ -69,7 +67,7 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor ...@@ -69,7 +67,7 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor
// Open Update Supervisor Form // Open Update Supervisor Form
$scope.update_supervisor = function(supervisor){ $scope.update_supervisor = function(supervisor){
// Hide (if it's show) the add form // Hide (if it's show) the add form
$scope.hidesupervisoradd = true; $scope.hidesupervisoradd = true;
// Show the update form // Show the update form
...@@ -87,7 +85,7 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor ...@@ -87,7 +85,7 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor
gender: supervisor.gender, gender: supervisor.gender,
lang: supervisor.lang, lang: supervisor.lang,
office: supervisor.office office: supervisor.office
}; };
}; };
// Save a Supervisor updated // Save a Supervisor updated
...@@ -108,37 +106,33 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor ...@@ -108,37 +106,33 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor
$http $http
.put(config.backend+'/supervisor/'+supid, supervisor) .put(config.backend+'/supervisor/'+supid, supervisor)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
$scope.showmessagesupervisor = true; $translate('supervisor_updated').then(function (translation) {
$scope.alertsupervisor = "alert-success"; ngToast.success({ content: translation });
$scope.messagesupervisor = "supervisor_updated"; });
// Update the view: Se recorre el array de objetos json para buscarlo // Update the view: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.supervisors.length; i++) { for(var i=0; i < $scope.supervisors.length; i++) {
if(supid == $scope.supervisors[i].id){ if(supid == $scope.supervisors[i].id){
$scope.supervisors[i].name = data.name; $scope.supervisors[i].name = data.name;
$scope.supervisors[i].surname = data.surname; $scope.supervisors[i].surname = data.surname;
$scope.supervisors[i].address = data.address; $scope.supervisors[i].address = data.address;
$scope.supervisors[i].country = data.country; $scope.supervisors[i].country = data.country;
$scope.supervisors[i].email = data.email; $scope.supervisors[i].email = data.email;
$scope.supervisors[i].phone = data.phone; $scope.supervisors[i].phone = data.phone;
$scope.supervisors[i].gender = data.gender; $scope.supervisors[i].gender = data.gender;
$scope.supervisors[i].lang = data.lang; $scope.supervisors[i].lang = data.lang;
$scope.supervisors[i].office = data.office; $scope.supervisors[i].office = data.office;
} }
} }
// Delete the fields of the form to avoid data binding // Delete the fields of the form to avoid data binding
// between the new element created and the form fields // between the new element created and the form fields
$scope.resetForm(); $scope.resetForm();
console.log("Supervisor updated");
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
$scope.showmessagesupervisor = true; $translate('supervisor_not_updated').then(function (translation) {
$scope.alertsupervisor = "alert-danger"; ngToast.danger({ content: translation });
$scope.messagesupervisor = "supervisor_not_updated"; });
console.log("Error from API: " + data.error);
}); });
}; };
...@@ -153,9 +147,9 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor ...@@ -153,9 +147,9 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor
$http $http
.post(config.backend+'/sup', supervisor) .post(config.backend+'/sup', supervisor)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
$scope.showmessagesupervisor = true; $translate('supervisor_added').then(function (translation) {
$scope.alertsupervisor = "alert-success"; ngToast.success({ content: translation });
$scope.messagesupervisor = "supervisor_added"; });
// Add to the list of supervisors in view // Add to the list of supervisors in view
$scope.supervisors.push(data.user); $scope.supervisors.push(data.user);
...@@ -164,15 +158,11 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor ...@@ -164,15 +158,11 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor
$scope.resetForm(); $scope.resetForm();
// Show the add form to new adding // Show the add form to new adding
$scope.hidesupervisoradd = false; $scope.hidesupervisoradd = false;
console.log("Supervisor added");
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
$scope.showmessagesupervisor = true; $translate('supervisor_not_added').then(function (translation) {
$scope.alertsupervisor = "alert-danger"; ngToast.danger({ content: translation });
$scope.messagesupervisor = "supervisor_not_added"; });
console.log("Error from API: " + data.error);
}); });
}; };
...@@ -183,29 +173,25 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor ...@@ -183,29 +173,25 @@ dashboardControllers.controller('AdminSupervisorsCtrl', function AdminSupervisor
$http $http
.delete(config.backend+'/supervisor/'+ supervisor.id) .delete(config.backend+'/supervisor/'+ supervisor.id)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo // Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.supervisors.length; i++) { for(var i=0; i < $scope.supervisors.length; i++) {
if(supervisor.id == $scope.supervisors[i].id) if(supervisor.id == $scope.supervisors[i].id)
$scope.supervisors.splice(i,1); $scope.supervisors.splice(i,1);
} }
console.log("Supervisor deleted:" + supervisor.name);
$scope.showmessagesupervisor = true; $translate('supervisor_deleted').then(function (translation) {
$scope.alertsupervisor = "alert-success"; ngToast.success({ content: translation });
$scope.messagesupervisor = "supervisor_deleted"; });
// Empty the form // Empty the form
$scope.resetForm(); $scope.resetForm();
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error deleting supervisor from API: " + data.error); $translate('supervisor_not_deleted').then(function (translation) {
console.log("It could be students associated"); ngToast.danger({ content: translation });
$scope.showmessagesupervisor = true; });
$scope.alertsupervisor = "alert-danger";
$scope.messagesupervisor = "supervisor_not_deleted";
}); });
} }
}; };
});
});
\ No newline at end of file
<!-- Admin Supervisors --> <!-- Admin Supervisors -->
<!-- Alert and success messages -->
<div ng-show="{{ 'showmessagesupervisor' }}" class="alert" ng-class="alertsupervisor">{{ messagesupervisor | translate }}</div>
<div class="row"> <div class="row">
<div ng-class="{'col-md-12':hidesupervisoradd === true && hidesupervisorupdate === true, 'col-md-8':hidesupervisoradd === false || hidesupervisorupdate === false}"> <div ng-class="{'col-md-12':hidesupervisoradd === true && hidesupervisorupdate === true, 'col-md-8':hidesupervisoradd === false || hidesupervisorupdate === false}">
......
/* global dashboardControllers */
'use strict'; 'use strict';
//------------------ //------------------
// Login Controller // Login Controller
//------------------ //------------------
dashboardControllers.controller('LoginCtrl', function LoginCtrl($scope, $http, $window, $translate, $filter, $location, config, $stateParams) { dashboardControllers.controller('LoginCtrl',
// The last parameter, config, is injected from config.js (defined in dashboardConfig module) function LoginCtrl(
$scope,
$http,
$window,
$translate,
$filter,
$location,
config,
$stateParams,
ngToast) {
$scope.credentials = { $scope.credentials = {
email: '', email: '',
password: '', password: '',
lang: 'es-es' lang: 'es-es'
}; };
// Pop-up blocker check
// var popup = window.open('http://yottacode.com','','',true);
// setTimeout( function() {
// if(!popup || popup.outerHeight === 0) {
// alert("cáspita");
// } else {
// popup && popup.close();
// }
// }, 100);
// Array of key terms to translate
$translate(['login_success', 'login_fail']).then(function (translations) {
//notification_email = translations.email_match;
$scope.message_success = translations.login_success;
$scope.message_fail = translations.login_fail;
});
// Don't show the message at the begining
$scope.showmessage = false;
// Validation of account // Validation of account
// if the code has been sent in the url "...app/login/code/email" // if the code has been sent in the url "...app/login/code/email"
if($stateParams.code && $stateParams.email){ if ($stateParams.code && $stateParams.email) {
console.log("Code: " + $stateParams.code + "\nEmail: " + $stateParams.email);
$http $http
.post(config.backend+'/sup/activate', $stateParams) .post(config.backend + '/sup/activate', $stateParams)
.success(function(data, status, headers, config) { .success(function () {
$scope.showmessage = true; $translate('account_activate').then(function (translation) {
$scope.alert = "alert-success"; ngToast.success({ content: translation });
$scope.message = "account_activate"; });
console.log("Supervisor: " + data.user.name);
//console.log("Account validated: " + data.user.email + " --> " + data.user.active);
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessage = true; $translate('account_no_activate').then(function (translation) {
$scope.alert = "alert-danger"; ngToast.danger({ content: translation });
$scope.message = "account_no_activate"; });
console.log("Account NOT validated! Error: " + data.error);
}); });
} }
$scope.login = function () { $scope.login = function () {
$http $http
.post(config.backend+'/sup/login', $scope.credentials) .post(config.backend + '/sup/login', $scope.credentials)
.success(function(data, status, headers, config) { .success(function (data) {
// Save token and user data y sessionStorage
$window.sessionStorage.token = data.token; $window.sessionStorage.token = data.token;
// Adapt language en-us to en-gb (the latter is the one supported for 'en') // Adapt language en-us to en-gb (the latter is the one supported for 'en')
if (data.user) { if (data.user) {
if (data.user.lang === 'en-us') if (data.user.lang === 'en-us') {
data.user.lang = 'en-gb'; data.user.lang = 'en-gb';
}
$scope.lang = data.user.lang; $scope.lang = data.user.lang;
} else {
$translate.use($scope.lang);
} }
else
console.log("ERROR: no data.user!");
$translate.use($scope.lang);
// Change // Change
$window.sessionStorage.user = JSON.stringify(data.user); $window.sessionStorage.user = JSON.stringify(data.user);
// Quitar 4 líneas siguientes. Al hacer redirección no hace falta $translate('login_success').then(function (translation) {
$scope.showmessage = true; ngToast.success({ content: translation });
$scope.alert = "alert-success"; });
$scope.message = "login_success";
// Name in login success message // Name in login success message
$scope.name = data.user.name; $scope.name = data.user.name;
console.log("logged in!");
// Redirección // Redirección
$location.path('/students'); $location.path('/students');
}) })
.error(function(data, status, headers, config) { .error(function () {
// Delete token if user fails to login
delete $window.sessionStorage.token; delete $window.sessionStorage.token;
$translate('login_fail').then(function (translation) {
$scope.showmessage = true; ngToast.danger({ content: translation });
$scope.alert = "alert-danger"; });
$scope.message = "login_fail";
}); });
} };
}); });
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
//------------------ //------------------
// Login Controller // Login Controller
//------------------ //------------------
dashboardControllers.controller('LoginAdminCtrl', function LoginAdminCtrl($scope, $http, $window, $translate, $location, config) { dashboardControllers.controller('LoginAdminCtrl', function LoginAdminCtrl($scope, $http, $window, $translate, $location, config, ngToast) {
// The last parameter, config, is injected from config.js (defined in dashboardConfig module) // The last parameter, config, is injected from config.js (defined in dashboardConfig module)
$scope.credentials = { $scope.credentials = {
...@@ -11,16 +11,6 @@ dashboardControllers.controller('LoginAdminCtrl', function LoginAdminCtrl($scope ...@@ -11,16 +11,6 @@ dashboardControllers.controller('LoginAdminCtrl', function LoginAdminCtrl($scope
password: '' password: ''
}; };
// Array of key terms to translate
$translate(['login_success', 'login_fail']).then(function (translations) {
//notification_email = translations.email_match;
$scope.message_success = translations.login_success;
$scope.message_fail = translations.login_fail;
});
// Don't show the message at the begining
$scope.showmessage = false;
$scope.login = function () { $scope.login = function () {
$http $http
.post(config.backend+'/admin/login', $scope.credentials) .post(config.backend+'/admin/login', $scope.credentials)
...@@ -29,15 +19,18 @@ dashboardControllers.controller('LoginAdminCtrl', function LoginAdminCtrl($scope ...@@ -29,15 +19,18 @@ dashboardControllers.controller('LoginAdminCtrl', function LoginAdminCtrl($scope
$window.sessionStorage.token = data.token; $window.sessionStorage.token = data.token;
// Redirect to admin panel // Redirect to admin panel
$location.path('/devices'); $location.path('/devices');
$translate('login_success').then(function(translation) {
ngToast.success({ content: translation });
});
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
// Delete token if user fails to login // Delete token if user fails to login
delete $window.sessionStorage.token; delete $window.sessionStorage.token;
$scope.showmessage = true; $translate('login_fail').then(function(translation) {
$scope.alert = "alert-danger"; ngToast.danger({ content: translation });
$scope.message = "login_fail"; });
}); });
}; };
});
});
\ No newline at end of file
...@@ -3,33 +3,26 @@ ...@@ -3,33 +3,26 @@
//----------------------------------- //-----------------------------------
// Login Setting Password Controller // Login Setting Password Controller
//----------------------------------- //-----------------------------------
dashboardControllers.controller('LoginSettingPasswordCtrl', function LoginSettingPasswordCtrl($scope, $http, $window, $translate, $location, config, $stateParams) { dashboardControllers.controller('LoginSettingPasswordCtrl', function LoginSettingPasswordCtrl($scope, $http, $window, $translate, $location, config, $stateParams, ngToast) {
// The last parameter, config, is injected from config.js (defined in dashboardConfig module)
// Array of key terms to translate
$translate(['validate_success', 'validate_fail']).then(function (translations) {
//notification_email = translations.email_match;
$scope.message_success = translations.validate_success;
$scope.message_fail = translations.validate_fail;
});
// Don't show the message at the begining
$scope.showmessage = false;
$scope.showlink = false;
$scope.login_setting_password = function () { $scope.login_setting_password = function () {
// Validation of account // Validation of account
// if the code has been sent in the url "...app/login/code/email" // if the code has been sent in the url "...app/login/code/email"
if($stateParams.code && $stateParams.email){ if ($stateParams.code && $stateParams.email) {
console.log("Code: " + $stateParams.code + "\nEmail: " + $stateParams.email);
// Validate password match // Validate password match
if($scope.password != $scope.password_confirm){ if ($scope.password != $scope.password_confirm) {
// ToDo: Highlight with Angular the input $translate([
$scope.showmessage = true; 'validate_fail',
$scope.alert = "alert-danger"; 'password_match'
$scope.message = "password_match"; ], function (translations) {
ngToast.danger({
content: [
translations.validate_fail,
translations.password_match
].join(': ')
});
});
return; return;
} }
...@@ -42,23 +35,15 @@ dashboardControllers.controller('LoginSettingPasswordCtrl', function LoginSettin ...@@ -42,23 +35,15 @@ dashboardControllers.controller('LoginSettingPasswordCtrl', function LoginSettin
$http $http
.post(config.backend+'/sup/activate', data) .post(config.backend+'/sup/activate', data)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
$scope.showmessage = true; $translate('validate_success').then(function (translation) {
$scope.showlink = true; ngToast.success({ content: translation });
$scope.hideform = true; });
$scope.alert = "alert-success";
$scope.message = "validate_success";
console.log("Supervisor: " + data.user.name);
//console.log("Account validated: " + data.user.email + " --> " + data.user.active);
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
$scope.showmessage = true; $translate('validate_fail').then(function (translation) {
$scope.alert = "alert-danger"; ngToast.danger({ content: translation });
$scope.message = "validate_fail"; });
console.log("Account NOT validated! Error: " + data.error);
}); });
} }
}; };
});
});
\ No newline at end of file
/* global dashboardControllers */
'use strict'; 'use strict';
//------------------- //-------------------
// SignIn Controller // SignIn Controller
//------------------- //-------------------
dashboardControllers.controller('SignInCtrl', function SignInCtrl($scope, $http, $window, reCAPTCHA, $translate, config) { dashboardControllers.controller('SignInCtrl',
// The last parameter, config, is injected from config.js (defined in dashboardConfig module) function SignInCtrl($scope,
// The previous parameter, $translate, is a dependency injection to translate text in JavaScript controller code $http,
$window,
// Data reCAPTCHA,
$translate,
config,
ngToast) {
$scope.formdata = { $scope.formdata = {
name: '', name: '',
surname: '', surname: '',
...@@ -23,69 +27,43 @@ dashboardControllers.controller('SignInCtrl', function SignInCtrl($scope, $http, ...@@ -23,69 +27,43 @@ dashboardControllers.controller('SignInCtrl', function SignInCtrl($scope, $http,
reCAPTCHA.setPublicKey('6LdLjh0TAAAAANblo_KUGNnmRZuIetOkdjdhj1b6'); reCAPTCHA.setPublicKey('6LdLjh0TAAAAANblo_KUGNnmRZuIetOkdjdhj1b6');
/* NOT NECESSARY
// Array of key terms to translate
$translate(['password_match', 'email_match']).then(function (translations) {
//notification_email = translations.email_match;
$scope.email_message = translations.email_match;
$scope.password_message = translations.password_match;
});
*/
// Verificar. Si no es necesario eliminar
//reCAPTCHA.setPublicKey('gazpacho andaluz');
// Don't show the message at the begining
$scope.showmessage = false;
// Form submit // Form submit
$scope.signin = function () { $scope.signin = function () {
//$scope.showmessage = false;
// Validate email match // Validate email match
if($scope.formdata.email != $scope.formdata.email_confirm){ if ($scope.formdata.email !== $scope.formdata.email_confirm) {
// ToDo: Highlight with Angular the input $translate('email_match').then(function (translation) {
$scope.showmessage = true; ngToast.danger({ content: translation });
$scope.alert = "alert-danger"; });
$scope.message = "email_match";
return; return;
} }
// Validate password match // Validate password match
if($scope.formdata.password != $scope.formdata.password_confirm){ if ($scope.formdata.password !== $scope.formdata.password_confirm) {
// ToDo: Highlight with Angular the input $translate('password_match').then(function (translation) {
$scope.showmessage = true; ngToast.danger({ content: translation });
$scope.alert = "alert-danger"; });
$scope.message = "password_match";
return; return;
} }
$scope.captcha = ""; $scope.captcha = '';
if($scope.signInForm.$valid) { if ($scope.signInForm.$valid) {
$scope.showdialog = true; $scope.showdialog = true;
console.log('Form is valid'); } else {
}else{
return; return;
} }
$http $http
.post(config.backend+'/sup', $scope.formdata) .post(config.backend + '/sup', $scope.formdata)
.success(function(data, status, headers, config) { .success(function () {
// ToDo: When this run well, redirect to main page $translate('user_created').then(function (translation) {
$scope.showmessage = true; ngToast.success({ content: translation });
$scope.alert = "alert-success"; });
$scope.message = "user_created";
console.log("User created");
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessage = true; $translate('user_exists').then(function (translation) {
$scope.alert = "alert-danger"; ngToast.danger({ content: translation });
$scope.message = "user_exists"; });
console.log("Error from API: " + status);
}); });
}; };
}); });
...@@ -13,14 +13,11 @@ ...@@ -13,14 +13,11 @@
<!-- LoginCtrl controls here, see app.js --> <!-- LoginCtrl controls here, see app.js -->
<form name="loginForm" ng-submit="login()" novalidate> <form name="loginForm" ng-submit="login()" novalidate>
<!-- Alert and success messages -->
<div ng-show="{{ 'showmessage' }}" class="alert" ng-class="alert" translate translate-value-name="{{name}}">{{message}}</div>
<div class="form-group"> <div class="form-group">
<input type="email" class="form-control" id="login_email" placeholder="{{ 'your_email' | translate}}" required ng-model="credentials.email" ng-focus="showmessage = false" /> <input type="email" class="form-control" id="login_email" placeholder="{{ 'your_email' | translate}}" required ng-model="credentials.email" />
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="login_password" placeholder="{{ 'your_password' | translate}}" required ng-model="credentials.password" ng-focus="showmessage = false" /> <input type="password" class="form-control" id="login_password" placeholder="{{ 'your_password' | translate}}" required ng-model="credentials.password" />
</div> </div>
<div class="checkbox"> <div class="checkbox">
<label> <label>
......
...@@ -12,9 +12,6 @@ ...@@ -12,9 +12,6 @@
<!-- Formulario --> <!-- Formulario -->
<!-- LoginAdminCtrl controls here, see app.js --> <!-- LoginAdminCtrl controls here, see app.js -->
<form name="loginForm" ng-submit="login()" novalidate> <form name="loginForm" ng-submit="login()" novalidate>
<!-- Alert and success messages -->
<div ng-show="{{ 'showmessage' }}" class="alert" ng-class="alert" translate translate-value-name="{{name}}">{{message}}</div>
<h3 class="text-center" translate>admin_login</h3> <h3 class="text-center" translate>admin_login</h3>
<div class="form-group"> <div class="form-group">
......
...@@ -11,9 +11,6 @@ ...@@ -11,9 +11,6 @@
<img src="img/logo_pictogram.png" alt="Pictogram" title="Pictogram" /> <img src="img/logo_pictogram.png" alt="Pictogram" title="Pictogram" />
</p> </p>
<!-- Alert and success messages -->
<div ng-show="{{ 'showmessage' }}" class="alert" ng-class="alert" translate translate-value-name="{{name}}">{{message}}</div>
<div ng-show="{{ 'showlink' }}" class="text-center"> <div ng-show="{{ 'showlink' }}" class="text-center">
<a href="/app/#/login" translate>click_login</a> <a href="/app/#/login" translate>click_login</a>
</div> </div>
...@@ -22,11 +19,11 @@ ...@@ -22,11 +19,11 @@
<form ng-hide="{{ 'hideform' }}" name="loginSettingPasswordForm" ng-submit="login_setting_password()"> <form ng-hide="{{ 'hideform' }}" name="loginSettingPasswordForm" ng-submit="login_setting_password()">
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="login_password" placeholder="{{ 'password_type' | translate}}" required ng-model="password" ng-focus="showmessage = false" /> <input type="password" class="form-control" id="login_password" placeholder="{{ 'password_type' | translate}}" required />
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="login_password_confirm" placeholder="{{ 'password_confirm' | translate}}" required ng-model="password_confirm" ng-focus="showmessage = false" /> <input type="password" class="form-control" id="login_password_confirm" placeholder="{{ 'password_confirm' | translate}}" required ng-model="password_confirm" />
</div> </div>
<p class="color_red text_sm text-center" ng-show="password != password_confirm" translate>password_match</p> <p class="color_red text_sm text-center" ng-show="password != password_confirm" translate>password_match</p>
......
...@@ -18,10 +18,6 @@ ...@@ -18,10 +18,6 @@
<!-- Formulario --> <!-- Formulario -->
<form name="signInForm" role="form" ng-submit="signin()"> <form name="signInForm" role="form" ng-submit="signin()">
<!-- Alert and success messages -->
<div ng-show="{{ 'showmessage' }}" class="alert" ng-class="alert" translate translate-values="{name: formdata.name, surname: formdata.surname, email: formdata.email}">{{message}}</div>
<fieldset> <fieldset>
<legend translate>personal_data</legend> <legend translate>personal_data</legend>
<div class="form-group"> <div class="form-group">
......
/* global dashboardControllers */
'use strict'; 'use strict';
// Please note that $modalInstance represents a modal window (instance) dependency. // Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above. // It is not the same as the $modal service used above.
dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance, $http, config, $window, $filter, $upload, stu_id, sup, studentPictos, categories, $modal) { dashboardControllers.controller('AddPictoCtrl', function (
$scope,
$modalInstance,
$http,
config,
$window,
$filter,
$upload,
stu_id,
sup,
studentPictos,
categories,
$modal,
$translate,
ngToast) {
var i;
var cat_id;
// Last 4 parameters passed from collections.js // Last 4 parameters passed from collections.js
// Basic data passed from the main window // Basic data passed from the main window
$scope.sup = sup; $scope.sup = sup;
...@@ -11,16 +29,16 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -11,16 +29,16 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
// Initially the source is symbolstx collection // Initially the source is symbolstx collection
$scope.source = 'symbolstx'; $scope.source = 'symbolstx';
// List of studentPictos // List of studentPictos
//console.log(JSON.stringify(studentPictos));
$scope.studentPictos = studentPictos; $scope.studentPictos = studentPictos;
// List of picto categories // List of picto categories
// console.log(JSON.stringify(categories)); // console.log(JSON.stringify(categories));
$scope.categories = categories; $scope.categories = categories;
// Array scope for pictos dragged into categories // Array scope for pictos dragged into categories
$scope.pictos_in_category = {}; $scope.pictos_in_category = {};
for(var i=0; i<$scope.categories.length;i++){
var cat_id = $scope.categories[i].picto.id; for (i = 0; i < $scope.categories.length; i++) {
$scope.pictos_in_category['cat'+cat_id]=[]; cat_id = $scope.categories[i].picto.id;
$scope.pictos_in_category['cat' + cat_id] = [];
} }
// List of actual pictos (showed by navigation) // List of actual pictos (showed by navigation)
...@@ -28,78 +46,72 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -28,78 +46,72 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
// List of categories (symbolstx) to show in navigation // List of categories (symbolstx) to show in navigation
$scope.symbolstxCats = []; $scope.symbolstxCats = [];
// List of breadcrumbs to show in navigation // List of breadcrumbs to show in navigation
$scope.breadcrumbs = []; $scope.breadcrumbs = [];
$scope.breadcrumbs.push({ id: 0, exp: 'Inicio', glyphicon: 'glyphicon glyphicon-home'}); $scope.breadcrumbs.push({ id: 0, exp: 'Inicio', glyphicon: 'glyphicon glyphicon-home' });
// Request of general pictos categories (symbolstx) // Request of general pictos categories (symbolstx)
$http $http.get(config.backend + '/sup/' + $scope.sup.id + '/pic_categories/0')
.get(config.backend+'/sup/'+ $scope.sup.id +'/pic_categories/0') .success(function (data) {
.success(function(data, status, headers, config) { $scope.symbolstxCats = data;
// Add to list })
$scope.symbolstxCats = data; .error(function () {
console.log("Symbolstx categories recovered"); $translate('error_loading_pictos').then(function (translation) {
ngToast.danger({ content: translation });
}) });
.error(function(data, status, headers, config) { });
console.log("Error from API: " + data.error);
});
// //
// Load pictos from a category // Load pictos from a category
// //
$scope.load_pictos = function (id_cat){ $scope.load_pictos = function (id_cat) {
$http $http.get(config.backend + '/sup/' + $scope.sup.id + '/pic_fromcategory/' + id_cat)
.get(config.backend+'/sup/'+ $scope.sup.id +'/pic_fromcategory/' + id_cat) .success(function (data) {
.success(function(data, status, headers, config) { if (data) {
// Add to list $scope.pictos = data;
if (data) } else {
$scope.pictos = data; $scope.pictos = [];
else $scope.pictos = []; }
//console.log(JSON.stringify($scope.pictos)); })
console.log("Pictos listed" + JSON.stringify(data)); .error(function () {
}) $translate('error_loading_pictos').then(function (translation) {
.error(function(data, status, headers, config) { ngToast.danger({ content: translation });
console.log("Error from API: " + data.error); });
}); });
}; };
// //
// Load pictos from owned by the actual supervisor // Load pictos from owned by the actual supervisor
// TEST --> change with real supervisor pictos // TEST --> change with real supervisor pictos
// //
$scope.load_own_pictos = function (){ $scope.load_own_pictos = function () {
$scope.source = 'ownpictos'; $scope.source = 'ownpictos';
$http $http.get(config.backend + '/sup/' + $scope.sup.id + '/pictos')
.get(config.backend+'/sup/'+ $scope.sup.id +'/pictos') .success(function (data) {
.success(function(data, status, headers, config) { if (data) {
// Add to list $scope.pictos = data;
if (data) } else {
$scope.pictos = data; $scope.pictos = [];
else $scope.pictos = []; }
console.log(JSON.stringify($scope.pictos)); })
console.log("Pictos listed"); .error(function () {
}) $translate('error_loading_pictos').then(function (translation) {
.error(function(data, status, headers, config) { ngToast.danger({ content: translation });
console.log("Error from API: " + data.error); });
}); });
}; };
// //
// Load the folders of a category // Load the folders of a category
// //
$scope.load_category = function (id_cat){ $scope.load_category = function (id_cat){
$http $http.get(config.backend+'/sup/'+ $scope.sup.id +'/pic_categories/' + id_cat)
.get(config.backend+'/sup/'+ $scope.sup.id +'/pic_categories/' + id_cat)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
// Add to list // Add to list
if (data) if (data)
$scope.symbolstxCats = data; $scope.symbolstxCats = data;
else $scope.symbolstxCats = []; else $scope.symbolstxCats = [];
console.log("Symbolstx categories recovered");
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
}); });
}; };
...@@ -108,9 +120,9 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -108,9 +120,9 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
// //
$scope.open_category = function (cat) { $scope.open_category = function (cat) {
// Add to breadcrumbs // Add to breadcrumbs
$scope.breadcrumbs.push({ $scope.breadcrumbs.push({
id: cat.id, id: cat.id,
exp: cat.exps[0].exp, exp: cat.exps[0].exp,
glyphicon: 'glyphicon glyphicon-chevron-right' glyphicon: 'glyphicon glyphicon-chevron-right'
}); });
...@@ -136,7 +148,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -136,7 +148,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
}; };
$scope.alert = { type: 'danger', msg: 'Category is full of pictos.', show: false }; $scope.alert = { type: 'danger', msg: 'Category is full of pictos.', show: false };
// //
// Close alert message // Close alert message
// //
...@@ -148,27 +160,27 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -148,27 +160,27 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
// Upload to own supervisor collection when a picto is selected from file // Upload to own supervisor collection when a picto is selected from file
// //
$scope.onPictoSelect = function($files) { $scope.onPictoSelect = function($files) {
//$files: an array of files selected, each file has name, size, and type. //$files: an array of files selected, each file has name, size, and type.
for (var i = 0; i < $files.length; i++) { for (var i = 0; i < $files.length; i++) {
var file = $files[i]; var file = $files[i];
// Check accepted file types // Check accepted file types
if(file.type == "image/jpeg" || file.type == "image/png" || file.type == "image/gif"){ if(file.type == "image/jpeg" || file.type == "image/png" || file.type == "image/gif"){
// Get the file extension // Get the file extension
var extension = file.name.split('.').pop(); var extension = file.name.split('.').pop();
var filename = sup.id + file.name; var filename = sup.id + file.name;
console.log("Archivo: " + filename); console.log("Archivo: " + filename);
//file.extra="{'filename': filename, 'extension': extension, 'folder': 'custompictos', 'owner': $scope.sup.id, 'source': '2'}"; //file.extra="{'filename': filename, 'extension': extension, 'folder': 'custompictos', 'owner': $scope.sup.id, 'source': '2'}";
$upload.upload({ $upload.upload({
url: '/picto/upload', //upload.php script, node.js route, or servlet url url: '/picto/upload', //upload.php script, node.js route, or servlet url
method: 'POST', // or 'PUT', method: 'POST', // or 'PUT',
// Fields to be sent in the body of the request // Fields to be sent in the body of the request
fields: {'filename': filename, 'extension': extension, 'folder': 'custompictos', 'owner': $scope.sup.id, 'source': '2'}, fields: {'filename': filename, 'extension': extension, 'folder': 'custompictos', 'owner': $scope.sup.id, 'source': '2'},
// or ['1.jpg', '2.jpg', ...] // to modify the name of the file(s) // or ['1.jpg', '2.jpg', ...] // to modify the name of the file(s)
file: file, // or list of files ($files) for html5 only file: file, // or list of files ($files) for html5 only
}).progress(function(evt) { }).progress(function(evt) {
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers, config) { }).success(function(data, status, headers, config) {
...@@ -204,7 +216,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -204,7 +216,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
var cat_y = parseInt(v_dest[2]); var cat_y = parseInt(v_dest[2]);
var pictosCategory = $filter('filter')($scope.studentPictos, { attributes: { id_cat: cat_id }}, true); var pictosCategory = $filter('filter')($scope.studentPictos, { attributes: { id_cat: cat_id }}, true);
//console.log(JSON.stringify(pictosCategory)); //console.log(JSON.stringify(pictosCategory));
// Build the pcb_cat with the coords of the pictos to assign the new picto near category picto // Build the pcb_cat with the coords of the pictos to assign the new picto near category picto
var rows = 5, cols = 10; var rows = 5, cols = 10;
...@@ -223,7 +235,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -223,7 +235,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
for(var i=0; i < pictosCategory.length; i++) { for(var i=0; i < pictosCategory.length; i++) {
var pic = pictosCategory[i]; var pic = pictosCategory[i];
// Compute the position in array // Compute the position in array
pcb_cat[pic.attributes.coord_x][pic.attributes.coord_y] = pic; pcb_cat[pic.attributes.coord_x][pic.attributes.coord_y] = pic;
} }
// Only for test // Only for test
...@@ -247,7 +259,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -247,7 +259,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
var x, y; var x, y;
while((iU>=0 || iD<rows) && !find){ while((iU>=0 || iD<rows) && !find){
if(iD<rows && !find){ if(iD<rows && !find){
// Actualizar iL e iR a la columna de la categoría // Actualizar iL e iR a la columna de la categoría
var iR = cat_y+1; var iR = cat_y+1;
var iL = cat_y; var iL = cat_y;
...@@ -286,7 +298,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -286,7 +298,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
} }
iU--; iD++; iU--; iD++;
} }
var uri = ""; var uri = "";
var p = {}; var p = {};
...@@ -296,19 +308,19 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -296,19 +308,19 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
// Show alert // Show alert
$scope.alert.show = true; $scope.alert.show = true;
console.log("Category is full. There is no free space for new pictos"); console.log("Category is full. There is no free space for new pictos");
}else{ }else{
// Close alert (if it's open) // Close alert (if it's open)
$scope.alert.show = false; $scope.alert.show = false;
// Search the item in left pictos // Search the item in left pictos
for(var i=0; i<$scope.pictos.length; i++){ for(var i=0; i<$scope.pictos.length; i++){
if(origin == $scope.pictos[i].id){ if(origin == $scope.pictos[i].id){
//$scope.pictos_in_category['cat'+cat_id].push($scope.pictos[i]); //$scope.pictos_in_category['cat'+cat_id].push($scope.pictos[i]);
//console.log("PICTO CATEGORY: " + JSON.stringify($scope.pictos_in_category['cat'+cat_id])); //console.log("PICTO CATEGORY: " + JSON.stringify($scope.pictos_in_category['cat'+cat_id]));
//console.log($scope.pictos_in_category['cat'+cat_id][0].uri); //console.log($scope.pictos_in_category['cat'+cat_id][0].uri);
//uri = $scope.pictos[i].uri; //uri = $scope.pictos[i].uri;
p = $scope.pictos[i]; p = $scope.pictos[i];
//console.log("PICTO FOUND: " + JSON.stringify(p)); //console.log("PICTO FOUND: " + JSON.stringify(p));
...@@ -318,7 +330,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -318,7 +330,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
// Update the origin picto coords in server (if the picto is not empty) // Update the origin picto coords in server (if the picto is not empty)
$http $http
.post(config.backend+'/stu/'+ $scope.stu_id + '/picto/' + .post(config.backend+'/stu/'+ $scope.stu_id + '/picto/' +
origin, { 'uri': p.uri, 'attributes': { 'id_cat': cat_id, 'coord_x': x , 'coord_y': y }}) origin, { 'uri': p.uri, 'attributes': { 'id_cat': cat_id, 'coord_x': x , 'coord_y': y }})
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
console.log('Picto ' + origin +' has been dropped to user '+ $scope.stu_id +' into picto --> ' + cat_id + '('+ cat_x +','+ cat_y +')'); console.log('Picto ' + origin +' has been dropped to user '+ $scope.stu_id +' into picto --> ' + cat_id + '('+ cat_x +','+ cat_y +')');
...@@ -340,10 +352,10 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -340,10 +352,10 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
io.socket.post('/stu/vocabulary', { io.socket.post('/stu/vocabulary', {
action: 'add', action: 'add',
attributes: { attributes: {
id_stu: $scope.stu_id, id_stu: $scope.stu_id,
picto: data picto: data
} }
}, },
function(res) { function(res) {
console.log("Vocabulary emitted: " + JSON.stringify(res.msg)); console.log("Vocabulary emitted: " + JSON.stringify(res.msg));
}); });
...@@ -352,30 +364,30 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -352,30 +364,30 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error); console.log("Error from API: " + data.error);
alert('Pictogram is already part of this vocabulary'); alert('Pictogram is already part of this vocabulary');
}); });
} }
}; };
// //
// Delete picto added // Delete picto added
// //
$scope.remove_picto = function (stuPicto, id_cat){ $scope.remove_picto = function (stuPicto, id_cat){
console.log("delete_studentPicto: " + JSON.stringify(stuPicto)); console.log("delete_studentPicto: " + JSON.stringify(stuPicto));
$http $http
.delete(config.backend+'/stu/'+ $scope.stu_id + '/picto/' + stuPicto.id) .delete(config.backend+'/stu/'+ $scope.stu_id + '/picto/' + stuPicto.id)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo // Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.studentPictos.length; i++) { for(var i=0; i < $scope.studentPictos.length; i++) {
if(stuPicto.id == $scope.studentPictos[i].id) if(stuPicto.id == $scope.studentPictos[i].id)
$scope.studentPictos.splice(i,1); $scope.studentPictos.splice(i,1);
} }
for(var i=0; i < $scope.pictos_in_category['cat'+id_cat].length; i++) { for(var i=0; i < $scope.pictos_in_category['cat'+id_cat].length; i++) {
if(stuPicto.id == $scope.pictos_in_category['cat'+id_cat][i].id) if(stuPicto.id == $scope.pictos_in_category['cat'+id_cat][i].id)
$scope.pictos_in_category['cat'+id_cat].splice(i,1); $scope.pictos_in_category['cat'+id_cat].splice(i,1);
} }
...@@ -386,10 +398,10 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -386,10 +398,10 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
io.socket.post('/stu/vocabulary', { io.socket.post('/stu/vocabulary', {
action: 'delete', action: 'delete',
attributes: { attributes: {
id_stu: $scope.stu_id, id_stu: $scope.stu_id,
picto: data picto: data
} }
}, },
function(res) { function(res) {
console.log("Vocabulary emitted: " + JSON.stringify(res.msg)); console.log("Vocabulary emitted: " + JSON.stringify(res.msg));
}); });
...@@ -399,7 +411,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -399,7 +411,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error); console.log("Error from API: " + data.error);
}); });
}; };
// //
...@@ -412,10 +424,10 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -412,10 +424,10 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
$http $http
.delete(config.backend+'/picto/'+ id_picto) .delete(config.backend+'/picto/'+ id_picto)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo // Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.pictos.length; i++) { for(var i=0; i < $scope.pictos.length; i++) {
if(id_picto == $scope.pictos[i].id) if(id_picto == $scope.pictos[i].id)
$scope.pictos.splice(i,1); $scope.pictos.splice(i,1);
} }
...@@ -424,7 +436,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance ...@@ -424,7 +436,7 @@ dashboardControllers.controller('AddPictoCtrl', function ($scope, $modalInstance
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error); console.log("Error from API: " + data.error);
}); });
} }
}; };
// //
......
/* global dashboardControllers */
'use strict'; 'use strict';
//----------------------- //-----------------------
// Student Setup Controller // Student Setup Controller
//----------------------- //-----------------------
dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($scope, $http, config, $stateParams, $window, $upload) { dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
$scope,
$http,
config,
$stateParams,
$window,
$upload,
$translate,
ngToast) {
// For tab navigation (here too, if the user refresh the page...) // For tab navigation (here too, if the user refresh the page...)
$scope.nav.tab = 'setup'; $scope.nav.tab = 'setup';
// When a picture is selected, launch the request // When a picture is selected, launch the request
$scope.onFileSelect = function($files) { $scope.onFileSelect = function ($files) {
//$files: an array of files selected, each file has name, size, and type. var i;
for (var i = 0; i < $files.length; i++) { var file;
var file = $files[i]; var extension;
var filename;
for (i = 0; i < $files.length; i++) {
file = $files[i]; // { name, size, type }
// Check accepted file types // Check accepted file types
if(file.type == "image/jpeg" || file.type == "image/png" || file.type == "image/gif"){ if (file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif') {
extension = file.name.split('.').pop();
// Get the file extension filename = $scope.studentData.id + file.name;
var extension = file.name.split('.').pop();
var filename = $scope.studentData.id + file.name;
console.log("Archivo: " + filename);
$upload.upload({ $upload.upload({
url: '/stu/upload', //upload.php script, node.js route, or servlet url url: '/stu/upload', // upload.php script, node.js route, or servlet url
method: 'POST', // or 'PUT', method: 'POST', // or 'PUT',
// Fields to sent in the body of the request fields: { // Fields to sent in the body of the request
fields: {'filename': filename, 'extension': extension, 'folder': 'students', 'id': $scope.studentData.id}, filename: filename,
// or ['1.jpg', '2.jpg', ...] // to modify the name of the file(s) extension: extension,
file: file, // or list of files ($files) for html5 only folder: 'students',
}).progress(function(evt) { id: $scope.studentData.id
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); },
}).success(function(data, status, headers, config) { file: file,
// file is uploaded successfully }).progress(function () {
console.log(JSON.stringify(data.file)); // TODO show progress to user
// Assign the new image with new name }).success(function (data) {
$scope.studentData.pic = "/upload/students/" + data.file.name; $translate('student_updated').then(function (translation) {
//$scope.picture = user.id + "." + extension + "?t=" + new Date().getTime(); ngToast.success({ content: translation });
});
$scope.studentData.pic = '/upload/students/' + data.file.name;
});
} else {
$translate('error_only_support_images').then(function (translation) {
ngToast.danger({ content: translation });
}); });
}else{
alert("It's only supported JPG, PNG and GIF files");
} }
} }
}; };
// Open calendar // Open calendar
$scope.open_calendar = function($event) { $scope.open_calendar = function ($event) {
$event.preventDefault(); $event.preventDefault();
$event.stopPropagation(); $event.stopPropagation();
...@@ -53,33 +66,30 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s ...@@ -53,33 +66,30 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s
}; };
// Save personal info updated // Save personal info updated
$scope.update_student = function(){ $scope.update_student = function () {
// Validate password match // Validate password match
if( $scope.formUser.password_confirm && if ($scope.formUser.password_confirm &&
!$scope.formUser.password_confirm.length && !$scope.formUser.password_confirm.length &&
$scope.formUser.password != $scope.formUser.password_confirm) { $scope.formUser.password !== $scope.formUser.password_confirm) {
// ToDo: Highlight with Angular the input $translate('password_match').then(function (translation) {
$scope.showmessage = true; ngToast.danger({ content: translation });
$scope.alert = "alert-danger"; });
$scope.message = "password_match";
return; return;
} }
// password not changed (don't send it to DB)
if ($scope.formUser.password_confirm && if ($scope.formUser.password_confirm &&
!$scope.formUser.password_confirm.length) { // password not changed (don't send it to DB) !$scope.formUser.password_confirm.length) {
delete $scope.formUser.password; delete $scope.formUser.password;
delete $scope.formUser.password_confirm; delete $scope.formUser.password_confirm;
} }
$http $http.put(config.backend + '/stu/' + $scope.studentData.id, $scope.formUser)
.put(config.backend+'/stu/'+$scope.studentData.id, $scope.formUser) .success(function (data) {
.success(function(data, status, headers, config) { $translate('student_updated').then(function (translation) {
$scope.showmessagestudent = true; ngToast.success({ content: translation });
$scope.alertstudent = "alert-success"; });
$scope.messagestudent = "student_updated";
// studentData with new values
$scope.studentData.surname = data.surname; $scope.studentData.surname = data.surname;
$scope.studentData.birthdate = data.birthdate; $scope.studentData.birthdate = data.birthdate;
$scope.studentData.country = data.country; $scope.studentData.country = data.country;
...@@ -87,145 +97,131 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s ...@@ -87,145 +97,131 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s
$scope.studentData.gender = data.gender; $scope.studentData.gender = data.gender;
$scope.studentData.lang = data.lang; $scope.studentData.lang = data.lang;
$scope.studentData.notes = data.notes; $scope.studentData.notes = data.notes;
console.log("Student updated");
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessagestudent = true; $translate.danger('student_not_updated', function (translation) {
$scope.alertstudent = "alert-danger"; ngToast.danger({ content: translation });
$scope.messagestudent = "student_not_updated"; });
console.log("Error from API: " + data.error);
}); });
}; };
// Search supervisor by email // Search supervisor by email
$scope.search_sup = function(){ $scope.search_sup = function () {
// Find tutor by email // Find tutor by email
$http $http.get([
.get(config.backend+'/sup?where={"email":"'+ $scope.email_sup +'", "office":{"!": null}}') config.backend,
.success(function(data, status, headers, config) { '/sup?where={"email":"',
// If it found the length is > 0 $scope.email_sup,
if(data.length > 0){ '", "office":{"!": null}}'
console.log("Supervisor found"); ].join(''))
.success(function (data) {
if (data.length > 0) {
$scope.supToAdd = data[0]; $scope.supToAdd = data[0];
// Show message for validate
$scope.showmessagesupfound = true; $scope.showmessagesupfound = true;
$scope.showmessagesupnotfound = false; $scope.showmessagesupnotfound = false;
}else{ } else {
console.log("Supervisor NOT found"); $translate('sup_not_found').then(function (translation) {
ngToast.danger({ content: translation });
$scope.showmessagesupnotfound = true; });
$scope.messagesup = "sup_not_found";
// Hide the success message (if it exists by other query) // Hide the success message (if it exists by other query)
$scope.showmessagesupfound = false; $scope.showmessagesupfound = false;
} }
}) })
.error(function(data, status, headers, config) { .error(function () {
$translate('sup_not_found').then(function (translation) {
console.log("Error from API: " + data.error); ngToast.danger({ content: translation });
});
}); });
}; };
// Add supervisor (father or mother) // Add supervisor (father or mother)
$scope.add_sup = function(){ $scope.add_sup = function () {
var stusup = { var stusup = {
student: $scope.studentData.id, student: $scope.studentData.id,
supervisor: $scope.supToAdd.id supervisor: $scope.supToAdd.id
} };
$http $http.get(config.backend + '/stu/' + $scope.studentData.id + '/sup/' + $scope.supToAdd.id)
.get(config.backend+'/stu/'+ $scope.studentData.id + '/sup/' + $scope.supToAdd.id) .success(function (data) {
.success(function(data, status, headers, config) {
// Assign the info of supervisor to add // Assign the info of supervisor to add
stusup.supervisor = $scope.supToAdd; stusup.supervisor = $scope.supToAdd;
stusup.id = data.id; stusup.id = data.id;
console.log(JSON.stringify(stusup));
// Add to the list of tutors in view // Add to the list of tutors in view
$scope.studentSupervisors.push($scope.supToAdd); $scope.studentSupervisors.push($scope.supToAdd);
// Delete the email form field // Delete the email form field
$scope.email_sup = ''; $scope.email_sup = '';
// Hide the message of supervisor founded // Hide the message of supervisor founded
$scope.showmessagesupfound = false; $scope.showmessagesupfound = false;
console.log("Supervisor added");
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessagesupnotfound = true; $translate('sup_not_added').then(function (translation) {
$scope.messagetutor = "sup_not_added"; ngToast.danger({ content: translation });
});
console.log("Error from API: " + data.error);
}); });
}; };
// Delete tutor // Delete tutor
$scope.delete_sup = function (id_sup){ $scope.delete_sup = function (id_sup) {
console.log("delete_supervisor:" + id_sup);
var deleteSup = $window.confirm('Are you absolutely sure you want to delete?'); var deleteSup = $window.confirm('Are you absolutely sure you want to delete?');
if(deleteSup){ if (deleteSup) {
$http $http.delete(config.backend + '/stu/' + $scope.studentData.id + '/sup/' + id_sup)
.delete(config.backend+'/stu/'+ $scope.studentData.id + '/sup/' + id_sup) .success(function () {
.success(function(data, status, headers, config) { var i;
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo // Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.studentSupervisors.length; i++) { for (i = 0; i < $scope.studentSupervisors.length; i++) {
if(id_sup == $scope.studentSupervisors[i].id) if (id_sup === $scope.studentSupervisors[i].id) {
$scope.studentSupervisors.splice(i,1); $scope.studentSupervisors.splice(i, 1);
}
} }
console.log("Supervisor deleted");
$translate('supervisor_deleted').then(function (translation) {
ngToast.success({ content: translation });
});
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessagesupnotfound = true; $translate('sup_not_deleted').then(function (translation) {
$scope.messagetutor = "sup_not_deleted"; ngToast.error({ content: translation });
});
console.log("Error from API: " + data.error);
}); });
} }
}; };
// Search tutor by email // Search tutor by email
$scope.search_tutor = function(){ $scope.search_tutor = function () {
// Find tutor by email // Find tutor by email
$http $http.get(config.backend + '/sup?where={"email":"' + $scope.email_tutor + '", "office":null}')
.get(config.backend+'/sup?where={"email":"'+ $scope.email_tutor +'", "office":null}') .success(function (data) {
.success(function(data, status, headers, config) {
// If it found the length is > 0 // If it found the length is > 0
if(data.length > 0){ if (data.length > 0) {
console.log("Tutor found");
$scope.tutorToAdd = data[0]; $scope.tutorToAdd = data[0];
// Show message for validate // Show message for validate
$scope.showmessagetutorfound = true; $scope.showmessagetutorfound = true;
$scope.showmessagetutornotfound = false; $scope.showmessagetutornotfound = false;
}else{ } else {
console.log("Tutor NOT found"); $translate('tutor_not_found').then(function (translation) {
ngToast.danger({ content: translation });
$scope.showmessagetutornotfound = true; });
$scope.messagetutor = "tutor_not_found";
// Hide the success message (if it exists by other query) // Hide the success message (if it exists by other query)
$scope.showmessagetutorfound = false; $scope.showmessagetutorfound = false;
} }
}) })
.error(function(data, status, headers, config) { .error(function () {
$translate('tutor_not_found').then(function (translation) {
console.log("Error from API: " + data.error); ngToast.danger({ content: translation });
});
}); });
}; };
// Add tutor // Add tutor
$scope.add_tutor = function(){ $scope.add_tutor = function () {
var stusup = { var stusup = {
student: $scope.studentData.id, student: $scope.studentData.id,
supervisor: $scope.tutorToAdd.id supervisor: $scope.tutorToAdd.id
} };
$http $http.get(config.backend + '/stu/' + $scope.studentData.id + '/sup/' + $scope.tutorToAdd.id)
.get(config.backend+'/stu/'+ $scope.studentData.id + '/sup/' + $scope.tutorToAdd.id) .success(function (data) {
.success(function(data, status, headers, config) {
// Assign the info of supervisor to add // Assign the info of supervisor to add
stusup.supervisor = $scope.tutorToAdd; stusup.supervisor = $scope.tutorToAdd;
stusup.id = data.id; stusup.id = data.id;
...@@ -236,54 +232,57 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s ...@@ -236,54 +232,57 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s
// Hide the message of tutor founded // Hide the message of tutor founded
$scope.showmessagetutorfound = false; $scope.showmessagetutorfound = false;
console.log("Tutor added"); $translate('tutor_added').then(function (translation) {
ngToast.success({ content: translation });
});
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessagetutornotfound = true; $translate('tutor_not_added').then(function (translation) {
$scope.messagetutor = "tutor_not_added"; ngToast.danger({ content: translation });
});
console.log("Error from API: " + data.error);
}); });
}; };
// Delete tutor // Delete tutor
$scope.delete_tutor = function (id_sup){ $scope.delete_tutor = function (id_sup) {
console.log("delete_tutor:" + id_sup);
var deleteTutor = $window.confirm('Are you absolutely sure you want to delete?'); var deleteTutor = $window.confirm('Are you absolutely sure you want to delete?');
if(deleteTutor){
$http if (deleteTutor) {
.delete(config.backend+'/stu/'+ $scope.studentData.id + '/sup/' + id_sup) $http.delete(config.backend + '/stu/' + $scope.studentData.id + '/sup/' + id_sup)
.success(function(data, status, headers, config) { .success(function () {
var i;
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo // Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.studentTutors.length; i++) { for (i = 0; i < $scope.studentTutors.length; i++) {
if(id_sup == $scope.studentTutors[i].id) if (id_sup === $scope.studentTutors[i].id) {
$scope.studentTutors.splice(i,1); $scope.studentTutors.splice(i, 1);
}
} }
console.log("Tutor deleted");
$translate('tutor_deleted').then(function (translation) {
ngToast.success({ content: translation });
});
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessagetutornotfound = true; $translate('tutor_not_deleted').then(function (translation) {
$scope.messagetutor = "tutor_not_deleted"; ngToast.danger({ content: translation });
});
console.log("Error from API: " + data.error);
}); });
} }
}; };
// TODO issue/357
$scope.delete_device = function (id_dev){ $scope.delete_device = function (id_dev){
var deleteDevice = $window.confirm('Are you absolutely sure you want to delete?'); var deleteDevice = $window.confirm('Are you absolutely sure you want to delete?');
if(deleteDevice){ if (deleteDevice) {
$http $http.delete(config.backend + '/stu/' + $scope.studentData.id + '/dev/' + id_dev)
.delete(config.backend+'/stu/'+ $scope.studentData.id +'/dev/' + id_dev)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
var i;
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo // Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.studentDevices.length; i++) { for (i = 0; i < $scope.studentDevices.length; i++) {
if(id_dev == $scope.studentDevices[i].id) if (id_dev == $scope.studentDevices[i].id) {
$scope.studentDevices.splice(i,1); $scope.studentDevices.splice(i,1);
}
} }
console.log("Device deleted with id " + id_dev); console.log("Device deleted with id " + id_dev);
...@@ -297,6 +296,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s ...@@ -297,6 +296,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s
} }
}; };
// TODO issue/357
$scope.associate_dev = function(){ $scope.associate_dev = function(){
var stu_dev = { var stu_dev = {
"id_stu": $scope.studentData.id, "id_stu": $scope.studentData.id,
...@@ -306,7 +306,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s ...@@ -306,7 +306,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s
$http $http
.post(config.backend+'/stu/dev/', stu_dev) .post(config.backend+'/stu/dev/', stu_dev)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
console.log("Created relation"); console.log("Created relation");
console.log(JSON.stringify(data)); console.log(JSON.stringify(data));
...@@ -315,7 +315,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s ...@@ -315,7 +315,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s
$scope.studentDevices.push(data); $scope.studentDevices.push(data);
// Remove the id from the input text form // Remove the id from the input text form
$scope.device_id_firmware = ''; $scope.device_id_firmware = '';
// Hide not found message if it is displayed // Hide not found message if it is displayed
$scope.showmessagedevnotfound = false; $scope.showmessagedevnotfound = false;
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
...@@ -357,4 +357,4 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s ...@@ -357,4 +357,4 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl($s
console.log("Error from API: " + data.error); console.log("Error from API: " + data.error);
}); });
}; };
}); });
\ No newline at end of file
/* global dashboardControllers, io */
'use strict'; 'use strict';
//----------------------- /**
// Student Controller * StudentCtrl
//----------------------- */
dashboardControllers.controller('StudentCtrl', function StudentCtrl($scope, config, $state, $http, $window, $filter, $rootScope) { dashboardControllers.controller('StudentCtrl', function StudentCtrl(
$scope,
config,
$state,
$http,
$window,
$filter,
$translate,
ngToast) {
var i;
var j;
$scope.studentData = { $scope.studentData = {
id: '', id: '',
username: '', username: '',
password: '', password: '',
password_confirm: '', password_confirm: '',
name: '', name: '',
surname: '', surname: '',
birthdate: '', birthdate: '',
country: '', country: '',
pic: '', pic: '',
gender: '', gender: '',
lang: '', lang: '',
notes: '', notes: '',
attributes: {}, attributes: {},
office: { office: {
id: '', id: '',
name: '' name: ''
}, },
stuSup: [], stuSup: [],
num_peers: 1 num_peers: 1
}; };
// For the user form data in setup section // For the user form data in setup section
...@@ -34,29 +46,29 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl($scope, conf ...@@ -34,29 +46,29 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl($scope, conf
// Accessing the idStudent defined in the states of tabs (student/XX/collections) // Accessing the idStudent defined in the states of tabs (student/XX/collections)
// from the abstract parent (it has no url) // from the abstract parent (it has no url)
$scope.studentData.id = $state.$current.locals.globals.$stateParams.idStudent; $scope.studentData.id = $state.$current.locals.globals.$stateParams.idStudent;
// //
// WebSockets communication // WebSockets communication
// //
io.socket.on('update_peers', function(data) { io.socket.on('update_peers', function (data) {
console.log(data.count + ' peers connected'); $translate('num_peers').then(function (translation) {
$scope.studentData.num_peers = data.count; ngToast.success(translation + ': ' + data.count);
});
$scope.studentData.num_peers = data.count;
}); });
io.socket.on('reconnect', function () { io.socket.on('reconnect', function () {
// Subscribe to student's socket room
// Subscribe to student's socket room io.socket.post('/stu/subscribe', {
console.log("reconnecting to socket"); action: 'subscribe',
io.socket.post('/stu/subscribe', { attributes: {
action: 'subscribe', id_stu: $scope.studentData.id
attributes:{ },
id_stu: $scope.studentData.id token: $window.sessionStorage.token
}, },
token: $window.sessionStorage.token function () {
}, // TODO ngToast res.msg (connected to student room)
function(res) { });
console.log("Connected to student: " + res.msg);
});
}); });
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
...@@ -65,214 +77,142 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl($scope, conf ...@@ -65,214 +77,142 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl($scope, conf
// //
// //
$http $http.get(config.backend + '/stu/' + $scope.studentData.id)
.get(config.backend+'/stu/' + $scope.studentData.id) .success(function (data) {
.success(function(data, status, headers, config) { $scope.studentData.id = data.id;
// studentData $scope.studentData.username = data.username;
$scope.studentData.id = data.id; $scope.studentData.name = data.name;
$scope.studentData.username = data.username; $scope.studentData.surname = data.surname;
$scope.studentData.name = data.name; $scope.studentData.birthdate = data.birthdate;
$scope.studentData.surname = data.surname; $scope.studentData.country = data.country;
$scope.studentData.birthdate = data.birthdate; $scope.studentData.pic = data.pic;
$scope.studentData.country = data.country; $scope.studentData.gender = data.gender;
$scope.studentData.pic = data.pic; $scope.studentData.lang = data.lang;
$scope.studentData.gender = data.gender; $scope.studentData.notes = data.notes;
$scope.studentData.lang = data.lang; $scope.studentData.office.id = data.office.id;
$scope.studentData.notes = data.notes; $scope.studentData.office.name = data.office.name;
$scope.studentData.office.id = data.office.id; $scope.studentData.stuSup = data.stuSup;
$scope.studentData.office.name = data.office.name; $scope.studentData.attributes = data.attributes;
$scope.studentData.stuSup = data.stuSup; $scope.studentData.current_method = data.current_method;
$scope.studentData.attributes = data.attributes; $scope.studentData.current_instruction = data.current_instruction;
$scope.studentData.current_method = data.current_method;
$scope.studentData.current_instruction = data.current_instruction; // Setup section: Fill formUser (data able to be modified) from studentData parent object
// It must go here to assign the values when studentData is recovered
// Setup section: Fill formUser (data able to be modified) from studentData parent object $scope.formUser.name = $scope.studentData.name;
// It must go here to assign the values when studentData is recovered $scope.formUser.username = $scope.studentData.username;
$scope.formUser.name = $scope.studentData.name; $scope.formUser.surname = $scope.studentData.surname;
$scope.formUser.username = $scope.studentData.username; $scope.formUser.birthdate = $scope.studentData.birthdate;
$scope.formUser.surname = $scope.studentData.surname; $scope.formUser.country = $scope.studentData.country;
$scope.formUser.birthdate = $scope.studentData.birthdate; $scope.formUser.pic = $scope.studentData.pic;
$scope.formUser.country = $scope.studentData.country; $scope.formUser.gender = $scope.studentData.gender;
$scope.formUser.pic = $scope.studentData.pic; $scope.formUser.lang = $scope.studentData.lang;
$scope.formUser.gender = $scope.studentData.gender; $scope.formUser.notes = $scope.studentData.notes;
$scope.formUser.lang = $scope.studentData.lang;
$scope.formUser.notes = $scope.studentData.notes; // Subscribe to student's socket room
io.socket.post('/stu/subscribe', {
console.log("Student personal data recovered"); action: 'subscribe',
console.log(JSON.stringify($scope.studentData)); attributes: {
console.log("Attributes: " + JSON.stringify($scope.studentData.attributes)); id_stu: $scope.studentData.id
console.log("Sups: " + JSON.stringify($scope.studentData.stuSup)); },
token: $window.sessionStorage.token
////////////////////////////////////////////////////////// },
// Subscribe to student's socket room function () {
console.log("connecting to socket"); // TODO ngToast res.msg (connected to student room)
io.socket.post('/stu/subscribe', {
action: 'subscribe',
attributes:{
id_stu: $scope.studentData.id
},
token: $window.sessionStorage.token
},
function(res) {
console.log("Connected to student: " + res.msg);
});
//////////////////////////////////////////////////////////
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
}); });
})
.error(function () {
// TODO ngToast res.msg (cant connect to student room)
});
// For tab navigation, initially blank goes to collections // For tab navigation, initially blank goes to collections
// Defined as JSON object to be available in in children as the same scope // Defined as JSON object to be available in in children as the same scope
$scope.nav = { $scope.nav = {
tab : 'collections' tab: 'collections'
}; };
// ----------------------------------------------------------------------
// COLLECTION
// Load student collection
//
// List of all student pictos // List of all student pictos
$scope.studentPictos = []; $scope.studentPictos = [];
// List of categories pictos // List of categories pictos
$scope.pictosCategory = []; $scope.pictosCategory = [];
// List of pictos from a catgory // List of pictos from a catgory
$scope.pictosFromCategory = []; $scope.pictosFromCategory = [];
// The view of pictos: All | Categories // The view of pictos: All | Categories
$scope.pictos = { $scope.pictos = {
category: null, category: null,
idCat: null idCat: null
}; };
// Initialization of PCB (the tablet view) and PCB-Categories // Initialization of PCB (the tablet view) and PCB-Categories
$scope.pcb_rows = 5, $scope.pcb_cols = 10; $scope.pcb_rows = 5;
$scope.pcb_cols = 10;
$scope.pcb = [];
$scope.pcb_cat = [];
$scope.pcb = new Array(); $scope.pcb_cat = new Array();
// Set the empty elements // Set the empty elements
for (var i=0;i<$scope.pcb_rows;i++) { for (i = 0; i < $scope.pcb_rows; i++) {
$scope.pcb[i]=new Array(); $scope.pcb_cat[i]=new Array(); $scope.pcb[i] = [];
for (var j=0;j<$scope.pcb_cols; j++) { $scope.pcb_cat[i] = [];
// Default value
$scope.pcb[i][j]={'picto': {'uri': '/app/img/empty.gif'}, 'attributes': {'coord_x': i, 'coord_y': j}}; for (j = 0; j < $scope.pcb_cols; j++) {
$scope.pcb_cat[i][j]={'picto': {'uri': '/app/img/empty.gif'}, 'attributes': {'coord_x': i, 'coord_y': j}}; $scope.pcb[i][j] = {
picto: { uri: '/app/img/empty.gif' },
attributes: { coord_x: i, coord_y: j }
};
$scope.pcb_cat[i][j] = {
picto: { uri: '/app/img/empty.gif' },
attributes: { coord_x: i, coord_y: j }
};
} }
} }
$http $http.get(config.backend + '/stu/' + $scope.studentData.id + '/pictos')
.get(config.backend+'/stu/'+ $scope.studentData.id +'/pictos') .success(function (data) {
.success(function(data, status, headers, config) { var k;
// Add to list var pic;
$scope.studentPictos = data;
//console.log(JSON.stringify($scope.pcb_cat));
$scope.pictosCategory = $filter('filter')($scope.studentPictos, {attributes: { id_cat: null }});
console.log("Pictos Categories: " + JSON.stringify($scope.pictosCategory));
// Build the pcb_cat with the coords of the pictos
for(var i=0; i < $scope.pictosCategory.length; i++) {
var pic = $scope.pictosCategory[i];
$scope.pcb_cat[pic.attributes.coord_x][pic.attributes.coord_y] = pic;
console.log("Pic " + pic.id + ": " + pic.attributes.color );
}
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
}); // Filtered only the categories pictos
////////////////////////////////////////////////////////////////////////////
// Devices /////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
/*
// For mark in list the actual device (Received from PCB via websocket)
$scope.active_device = null;
// 1) Leer los dispositivos del alumno y mostrar en listado
// Array with student's devices
$scope.devices = [];
// Query to obtain an array of student devices
$http
.get(config.backend+'/stu/'+ $scope.studentData.id +'/devices')
.success(function(data, status, headers, config) {
// Add to list
$scope.devices = data;
console.log(JSON.stringify($scope.devices));
console.log("Devices recovered");
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
*/
// ----------------------------------------------------------------------
// REPORTS
// Load information for reports
//
//
// NOTE: this information is created when the tab is selected, so information
// is always updated
// ---------------------------------------------------------------------- $scope.studentPictos = data;
// SETUP $scope.pictosCategory = $filter('filter')($scope.studentPictos, {
// Load student configuration attributes: {
// id_cat: null
}
});
// Build the pcb_cat with the coords of the pictos
for (k = 0; k < $scope.pictosCategory.length; k++) {
pic = $scope.pictosCategory[k];
$scope.pcb_cat[pic.attributes.coord_x][pic.attributes.coord_y] = pic;
}
})
.error(function () {
$translate('error_loading_pictos').then(function (translation) {
ngToast.danger({ content: translation });
});
});
// *******************************************************
// Therapists
// List of student's therapists
$scope.studentSupervisors = []; $scope.studentSupervisors = [];
$http.get(config.backend + '/stu/' + $scope.studentData.id + '/therapists')
.success(function (data) {
$scope.studentSupervisors = data;
})
.error(function () {
// TODO show error with ngToast
});
$http
.get(config.backend+'/stu/'+ $scope.studentData.id +'/therapists')
.success(function(data, status, headers, config) {
// Add to list
$scope.studentSupervisors = data;
console.log(JSON.stringify($scope.studentSupervisors));
console.log("Supervisors listed");
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
// List of student's tutors (parents)
$scope.studentTutors = []; $scope.studentTutors = [];
$http.get(config.backend + '/stu/' + $scope.studentData.id + '/tutors')
$http .success(function (data) {
.get(config.backend+'/stu/'+ $scope.studentData.id +'/tutors') $scope.studentTutors = data;
.success(function(data, status, headers, config) { })
// Add to list .error(function () {
$scope.studentTutors = data; // TODO show error with ngToast
console.log(JSON.stringify($scope.studentTutors)); });
console.log("Tutors listed");
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
// *******************************************************
// Devices
// List of student's devices
$scope.studentDevices = []; $scope.studentDevices = [];
$http.get(config.backend + '/stu/' + $scope.studentData.id + '/devices')
$http .success(function (data) {
.get(config.backend+'/stu/'+ $scope.studentData.id +'/devices') $scope.studentDevices = data;
.success(function(data, status, headers, config) { })
// Add to list .error(function () {
$scope.studentDevices = data; // TODO show error with ngToast
console.log("Devices listed: "); });
console.log(JSON.stringify($scope.studentDevices));
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
/*
// Events handling
io.socket.on('action', function(data) {
console.log('"action" event received with the following data:');
console.log(data.msg);
});*/
}); });
'use strict'; /* global dashboardControllers */
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
dashboardControllers.controller('TagsCtrl', function ($scope, $modalInstance, $http, config, stuPicto, sup) { 'use strict';
// Last parameter passed from collections.js
// Basic data passed from the main window
/**
* TagsCtrl
*/
dashboardControllers.controller('TagsCtrl', function TagsCtrl(
$scope,
$modalInstance,
$http,
config,
stuPicto,
sup,
$translate,
ngToast) {
// Supervisor // Supervisor
$scope.sup = sup; $scope.sup = sup;
// List of general tags // List of general tags
...@@ -15,66 +22,62 @@ dashboardControllers.controller('TagsCtrl', function ($scope, $modalInstance, $h ...@@ -15,66 +22,62 @@ dashboardControllers.controller('TagsCtrl', function ($scope, $modalInstance, $h
$scope.ownTags = []; $scope.ownTags = [];
// Request of general tags // Request of general tags
$http $http.get(config.backend + '/picto/' + stuPicto.picto.id)
.get(config.backend+'/picto/' + stuPicto.picto.id) .success(function (data) {
.success(function(data, status, headers, config) { $scope.tags = data.tags;
// Add to lists $scope.ownTags = data.tagsSup;
$scope.tags = data.tags; })
$scope.ownTags = data.tagsSup; .error(function () {
console.log("Tags recovered"); $translate('error_loading_pictos').then(function (translation) {
}) ngToast.danger({ content: translation });
.error(function(data, status, headers, config) { });
console.log("Error from API: " + data.error); });
});
// Add own tag // Add own tag
$scope.add = function () { $scope.add = function () {
$http.post(config.backend + '/picto/tag',
$http {
.post(config.backend+'/picto/tag', picto: stuPicto.picto.id,
{ 'picto': stuPicto.picto.id, supervisor: $scope.sup.id,
'supervisor': $scope.sup.id, tag: $scope.tagToAdd,
'tag': $scope.tagToAdd, lang: $scope.sup.lang
'lang': $scope.sup.lang }
}) )
.success(function(data, status, headers, config) { .success(function (data) {
console.log("Tag added: " + JSON.stringify(data)); $scope.ownTags.push(data);
$scope.tagToAdd = '';
$scope.ownTags.push(data); })
$scope.tagToAdd = ""; .error(function () {
}) // TODO show error with ngToast
.error(function(data, status, headers, config) { });
console.log("Error from API: " + data.error);
});
}; };
// Destroy own tag // Destroy own tag
$scope.del = function (tag) { $scope.del = function (tag) {
$http.delete(config.backend + '/picto/tag/' + tag.id)
$http .success(function () {
.delete(config.backend+'/picto/tag/' + tag.id) var i;
.success(function(data, status, headers, config) { // TODO show success with ngToast
console.log("Tag destroyed: " + JSON.stringify(data)); // Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for (i = 0; i < $scope.ownTags.length; i++) {
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo if (tag.id === $scope.ownTags[i].id) {
for(var i=0; i < $scope.ownTags.length; i++) { $scope.ownTags.splice(i, 1);
if(tag.id == $scope.ownTags[i].id)
$scope.ownTags.splice(i,1);
} }
}
}) })
.error(function(data, status, headers, config) { .error(function () {
console.log("Error from API: " + data.error); // TODO show error with ngToast
}); });
}; };
$scope.close = function () { $scope.close = function () {
$modalInstance.close("Ejemplo de elemento devuelto"); // TODO ¿?¿?
$modalInstance.close('Ejemplo de elemento devuelto');
}; };
// No usado // No usado
$scope.cancel = function () { $scope.cancel = function () {
// TODO ¿?¿?
$modalInstance.dismiss('cancel'); $modalInstance.dismiss('cancel');
}; };
}); });
<toast></toast>
<!-- Instrucction tab--> <!-- Instrucction tab-->
<div class="panel panel-default student_tab_panel"> <div class="panel panel-default student_tab_panel">
......
<div class="panel panel-default student_tab_panel"> <div class="panel panel-default student_tab_panel">
<div class="panel-body">
<!-- Alert and success messages -->
<div ng-show="{{ 'showmessagestudent' }}" class="alert" ng-class="alertstudent">{{ messagestudent | translate }}</div>
<div class="panel-body">
<div class="row"> <div class="row">
<!-- Parte izquierda: Datos personales --> <!-- Parte izquierda: Datos personales -->
<div class="col-md-6"> <div class="col-md-6">
...@@ -19,7 +15,7 @@ ...@@ -19,7 +15,7 @@
</div> </div>
<!-- Preview --> <!-- Preview -->
<img class="thumbnail preview" ng-src="{{studentData.pic}}" /> <img class="thumbnail preview" ng-src="{{studentData.pic}}" />
<!-- Fin Cambiar imagen de perfil --> <!-- Fin Cambiar imagen de perfil -->
<!-- Datos personales del alumno --> <!-- Datos personales del alumno -->
...@@ -100,7 +96,7 @@ ...@@ -100,7 +96,7 @@
<!-- Supervisores (terapeutas) del alumno --> <!-- Supervisores (terapeutas) del alumno -->
<div id="student_sups"> <div id="student_sups">
<h4 translate>supervisors</h4> <h4 translate>supervisors</h4>
<!-- Buscador de supervisores --> <!-- Buscador de supervisores -->
<p> <p>
<form role="search" ng-submit="search_sup()"> <form role="search" ng-submit="search_sup()">
<div class="input-group"> <div class="input-group">
...@@ -117,11 +113,9 @@ ...@@ -117,11 +113,9 @@
<!-- Alert and success messages for supervisor found --> <!-- Alert and success messages for supervisor found -->
<div ng-show="{{ 'showmessagesupfound' }}" class="alert alert-info"> <div ng-show="{{ 'showmessagesupfound' }}" class="alert alert-info">
<!-- Imagen de perfil del tutor --> <!-- Imagen de perfil del tutor -->
<img ng-src="{{supToAdd.pic}}" class="profile" alt="" title="" /> {{ supToAdd.name }} {{ supToAdd.surname }} <img ng-src="{{supToAdd.pic}}" class="profile" alt="" title="" /> {{ supToAdd.name }} {{ supToAdd.surname }}
<a class="btn btn-default btn-lg pull-right" role="button" ng-click="add_sup()" translate>add</a> <a class="btn btn-default btn-lg pull-right" role="button" ng-click="add_sup()" translate>add</a>
</div> </div>
<div ng-show="{{ 'showmessagesupnotfound' }}" class="alert alert-warning">{{ messagesup | translate }}</div>
<!-- Fin de buscador de supervisores --> <!-- Fin de buscador de supervisores -->
<!-- Supervisores asignados --> <!-- Supervisores asignados -->
...@@ -135,14 +129,14 @@ ...@@ -135,14 +129,14 @@
</a> </a>
</li> </li>
</ul> </ul>
<!-- Fin de Supervisores asignados --> <!-- Fin de Supervisores asignados -->
</div> </div>
<!-- Fin de id student-sups --> <!-- Fin de id student-sups -->
<!-- Tutores (Padres) --> <!-- Tutores (Padres) -->
<div id="student_tutors"> <div id="student_tutors">
<h4>{{ 'tutors' | translate }}</h4> <h4>{{ 'tutors' | translate }}</h4>
<!-- Buscador de tutores --> <!-- Buscador de tutores -->
<p> <p>
<form role="search" ng-submit="search_tutor()"> <form role="search" ng-submit="search_tutor()">
<div class="input-group"> <div class="input-group">
...@@ -159,11 +153,9 @@ ...@@ -159,11 +153,9 @@
<!-- Alert and success messages for tutor found --> <!-- Alert and success messages for tutor found -->
<div ng-show="{{ 'showmessagetutorfound' }}" class="alert alert-info"> <div ng-show="{{ 'showmessagetutorfound' }}" class="alert alert-info">
<!-- Imagen de perfil del tutor --> <!-- Imagen de perfil del tutor -->
<img ng-src="{{tutorToAdd.pic}}" class="profile" alt="" title="" /> {{ tutorToAdd.name }} {{ tutorToAdd.surname }} <img ng-src="{{tutorToAdd.pic}}" class="profile" alt="" title="" /> {{ tutorToAdd.name }} {{ tutorToAdd.surname }}
<a class="btn btn-default btn-sm pull-right" role="button" ng-click="add_tutor()" translate>add</a> <a class="btn btn-default btn-sm pull-right" role="button" ng-click="add_tutor()" translate>add</a>
</div> </div>
<div ng-show="{{ 'showmessagetutornotfound' }}" class="alert alert-warning">{{ messagetutor | translate }}</div>
<!-- Fin de buscador de tutores --> <!-- Fin de buscador de tutores -->
<!-- Tutores asignados --> <!-- Tutores asignados -->
...@@ -177,7 +169,7 @@ ...@@ -177,7 +169,7 @@
</a> </a>
</li> </li>
</ul> </ul>
<!-- Fin de Tutores asignados --> <!-- Fin de Tutores asignados -->
<!-- Info message --> <!-- Info message -->
<div class="alert alert-info">{{ 'supervisor_note' | translate }}</div> <div class="alert alert-info">{{ 'supervisor_note' | translate }}</div>
...@@ -187,7 +179,7 @@ ...@@ -187,7 +179,7 @@
<!-- Student devices --> <!-- Student devices -->
<div id="student_devices"> <div id="student_devices">
<h4 translate>devices</h4> <h4 translate>devices</h4>
<!-- Formulario para introducir ID de dispositivo --> <!-- Formulario para introducir ID de dispositivo -->
<p> <p>
<form role="search" ng-submit="associate_dev()"> <form role="search" ng-submit="associate_dev()">
<div class="input-group"> <div class="input-group">
...@@ -208,17 +200,17 @@ ...@@ -208,17 +200,17 @@
<!-- Dispositivos asignados --> <!-- Dispositivos asignados -->
<ul class="list-group" id="user_devices"> <ul class="list-group" id="user_devices">
<li class="list-group-item" ng-repeat="dev in studentDevices"> <li class="list-group-item" ng-repeat="dev in studentDevices">
<span class="glyphicon glyphicon-phone" aria-hidden="true"></span> {{dev.desc}} <span class="glyphicon glyphicon-phone" aria-hidden="true"></span> {{dev.desc}}
<!-- aquí mejor stusupdev.id --> <!-- aquí mejor stusupdev.id -->
<a ng-click="delete_device(dev.id)" class="delete_device" title="{{ 'unlink' | translate }}"> <a ng-click="delete_device(dev.id)" class="delete_device" title="{{ 'unlink' | translate }}">
<span class="color_red glyphicon glyphicon-remove-circle" aria-hidden="true"></span> <span class="color_red glyphicon glyphicon-remove-circle" aria-hidden="true"></span>
</a> </a>
</li> </li>
</ul> </ul>
<!-- Fin de Dispositivos asignados --> <!-- Fin de Dispositivos asignados -->
</div> </div>
<!-- Fin de id student-devices --> <!-- Fin de id student-devices -->
</div> </div>
</div> </div>
<!-- Fin de row --> <!-- Fin de row -->
...@@ -239,9 +231,9 @@ ...@@ -239,9 +231,9 @@
<legend translate>pictograms</legend> <legend translate>pictograms</legend>
<div class="input-group"> <div class="input-group">
<label>{{ 'background' | translate }}: <label>{{ 'background' | translate }}:
<input id="picto_background" type="color" ng-model="studentData.attributes.picto_background" ng-mouseleave="update_attributes()" /> <input id="picto_background" type="color" ng-model="studentData.attributes.picto_background" ng-mouseleave="update_attributes()" />
</label> </label>
</div> </div>
<h4>{{ 'size' | translate }}:</h4> <h4>{{ 'size' | translate }}:</h4>
...@@ -293,9 +285,9 @@ ...@@ -293,9 +285,9 @@
<legend translate>phrase_tape</legend> <legend translate>phrase_tape</legend>
<div class="input-group"> <div class="input-group">
<label>{{ 'background' | translate }}: <label>{{ 'background' | translate }}:
<input id="phrase_background" type="color" ng-model="studentData.attributes.phrase_background" ng-mouseleave="update_attributes()" /> <input id="phrase_background" type="color" ng-model="studentData.attributes.phrase_background" ng-mouseleave="update_attributes()" />
</label> </label>
</div> </div>
<h4>{{ 'place_pictos' | translate }}:</h4> <h4>{{ 'place_pictos' | translate }}:</h4>
...@@ -306,7 +298,7 @@ ...@@ -306,7 +298,7 @@
<label class="btn btn-success" ng-model="studentData.attributes.input_selection" btn-radio="'press'" ng-change="update_attributes()">{{ 'press' | translate }}</label> <label class="btn btn-success" ng-model="studentData.attributes.input_selection" btn-radio="'press'" ng-change="update_attributes()">{{ 'press' | translate }}</label>
--> -->
<label class="btn btn-success" ng-model="studentData.attributes.input_selection" btn-radio="'drag'" ng-change="update_attributes()">{{ 'drag' | translate }}</label> <label class="btn btn-success" ng-model="studentData.attributes.input_selection" btn-radio="'drag'" ng-change="update_attributes()">{{ 'drag' | translate }}</label>
</div> </div>
<h4>{{ 'feedback_picto' | translate }}:</h4> <h4>{{ 'feedback_picto' | translate }}:</h4>
<div class="btn-group"> <div class="btn-group">
...@@ -315,7 +307,7 @@ ...@@ -315,7 +307,7 @@
<label class="btn btn-success" ng-model="studentData.attributes.input_feedback.read" btn-checkbox ng-change="update_attributes()">{{ 'read_picto' | translate }}</label> <label class="btn btn-success" ng-model="studentData.attributes.input_feedback.read" btn-checkbox ng-change="update_attributes()">{{ 'read_picto' | translate }}</label>
<label class="btn btn-success" ng-model="studentData.attributes.input_feedback.highlight" btn-checkbox ng-change="update_attributes()">{{ 'highlight' | translate }}</label> <label class="btn btn-success" ng-model="studentData.attributes.input_feedback.highlight" btn-checkbox ng-change="update_attributes()">{{ 'highlight' | translate }}</label>
</div> </div>
</fieldset> </fieldset>
<!-- Ajustes de voz --> <!-- Ajustes de voz -->
...@@ -349,6 +341,6 @@ ...@@ -349,6 +341,6 @@
<!-- Fin de Configuración de los dispositivos --> <!-- Fin de Configuración de los dispositivos -->
</div> </div>
<!-- Fin de panel body --> <!-- Fin de panel body -->
</div> </div>
<!-- Fin de panel --> <!-- Fin de panel -->
\ No newline at end of file
/* global dashboardControllers */
'use strict'; 'use strict';
//------------------ /**
// Setup Controller * SetupCtrl
//------------------ */
dashboardControllers.controller('SetupCtrl', function SetupCtrl($scope, $http, $window, $translate, $location, $upload, config) { dashboardControllers.controller('SetupCtrl', function SetupCtrl(
// The last parameter, config, is injected from config.js (defined in dashboardConfig module) $scope,
$http,
$window,
$translate,
$location,
$upload,
ngToast,
config) {
var user;
// Don't show the message at the begining // Don't show the message at the begining
$scope.showmessage = false; $scope.showmessage = false;
// Restore user values from sessionStorage // Restore user values from sessionStorage
var user = JSON.parse($window.sessionStorage.user); user = JSON.parse($window.sessionStorage.user);
// Fill the form with the user data
$scope.formdata = user; $scope.formdata = user;
// Testing --> DELETE
console.log("User id: " + user.id.toString());
console.log("User id to hashcode: " + user.id.toString().hashCode());
// When a picture is selected, launch the request // When a picture is selected, launch the request
$scope.onFileSelect = function($files) { $scope.onFileSelect = function ($files) {
//$files: an array of files selected, each file has name, size, and type. var i;
for (var i = 0; i < $files.length; i++) { var file;
var file = $files[i]; var extension;
var filename;
// Check accepted file types
if(file.type == "image/jpeg" || file.type == "image/png" || file.type == "image/gif"){ for (i = 0; i < $files.length; i++) {
file = $files[i]; // { name, size, type }
// Get the file extension if (file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif') {
var extension = file.name.split('.').pop(); extension = file.name.split('.').pop();
var filename = user.id + file.name; filename = user.id + file.name;
console.log("Archivo: " + filename);
$upload.upload({ $upload.upload({
url: '/sup/upload', //upload.php script, node.js route, or servlet url url: '/sup/upload', // upload.php script, node.js route, or servlet url
method: 'POST', // or 'PUT', method: 'POST', // or 'PUT',
// Fields to sent in the body of the request fields: {
fields: {'filename': filename, 'extension': extension, 'folder': 'supervisors', 'id': user.id}, filename: filename,
// or ['1.jpg', '2.jpg', ...] // to modify the name of the file(s) extension: extension,
file: file, // or list of files ($files) for html5 only folder: 'supervisors',
}).progress(function(evt) { id: user.id
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total)); },
}).success(function(data, status, headers, config) { file: file
// file is uploaded successfully })
console.log(JSON.stringify(data.file)); .progress(function () {
// Assign the new image with new name // TODO show file upload progress to user
$scope.user.pic = "/upload/supervisors/" + data.file.name; })
//$scope.picture = user.id + "." + extension + "?t=" + new Date().getTime(); .success(function (data) {
// Modify the user in session // TODO show success ngToast
var user = JSON.parse($window.sessionStorage.user); $scope.user.pic = '/upload/supervisors/' + data.file.name;
user.pic = $scope.user.pic; user.pic = $scope.user.pic;
$window.sessionStorage.user = JSON.stringify(user); $window.sessionStorage.user = JSON.stringify(user);
}); });
}else{ } else {
alert("It's only supported JPG, PNG and GIF files"); $translate('error_only_support_images').then(function (translation) {
ngToast.error({ content: translation });
});
} }
} }
}; };
// Form submit // Form submit
$scope.setup = function () { $scope.setup = function () {
var supervisor;
var actualEmail;
//$scope.showmessage = false; if ($scope.formdata.password !== $scope.formdata.password_confirm) {
$translate('password_match').then(function (translation) {
// Validate password match ngToast.danger({ content: translation });
if($scope.formdata.password != $scope.formdata.password_confirm){ });
// ToDo: Highlight with Angular the input
$scope.showmessage = true;
$scope.alert = "alert-danger";
$scope.message = "password_match";
return; return;
} }
if($scope.setupForm.$valid) { if (!$scope.setupForm.$valid) {
// $scope.showdialog = true; $translate('invalid_fields').then(function (translation) {
console.log('Form is valid'); ngToast.danger({ content: translation });
}else{ });
return; return;
} }
var supervisor = $scope.formdata; supervisor = $scope.formdata;
var actual_email = JSON.parse($window.sessionStorage.user).email; actualEmail = JSON.parse($window.sessionStorage.user).email;
// Comprobation for new email // Comprobation for new email
// If no change, it is deleted from supervisor object // If no change, it is deleted from supervisor object
if(supervisor.email == actual_email) if (supervisor.email === actualEmail) {
delete supervisor.email; delete supervisor.email;
}
// console.log($scope.formdata.uploadFile);
$http $http.put(config.backend + '/sup', supervisor)
.put(config.backend+'/sup', supervisor) .success(function (data) {
.success(function(data, status, headers, config) { $translate('data_saved').then(function (translation) {
// ToDo: When this run well, redirect to main page ngToast.success({ content: translation });
$scope.showmessage = true; });
$scope.alert = "alert-success";
$scope.message = "data_saved";
// Modify the name in the header // Modify the name in the header
$scope.name = data.name + " " + data.surname; $scope.name = data.name + ' ' + data.surname;
// Modify the user data in session // Modify the user data in session
user.name = data.name; user.name = data.name;
user.surname = data.surname; user.surname = data.surname;
...@@ -113,16 +114,11 @@ dashboardControllers.controller('SetupCtrl', function SetupCtrl($scope, $http, $ ...@@ -113,16 +114,11 @@ dashboardControllers.controller('SetupCtrl', function SetupCtrl($scope, $http, $
delete user.password_confirm; delete user.password_confirm;
$window.sessionStorage.user = JSON.stringify(user); $window.sessionStorage.user = JSON.stringify(user);
console.log("User modified");
}) })
.error(function(data, status, headers, config) { .error(function () {
$scope.showmessage = true; $translate('data_no_saved').then(function (translation) {
$scope.alert = "alert-danger"; ngToast.danger({ content: translation });
$scope.message = "data_no_saved"; });
console.log("Error from API: " + data.error);
}); });
}; };
}); });
\ No newline at end of file
'use strict'; /* global dashboardControllers, io */
//------------------ 'use strict';
// Students Controller
//------------------
dashboardControllers.controller('StudentsCtrl', function StudentsCtrl($scope, $state, $http, config, $window, $translate, ngToast) {
/**
* StudentsCtrl
*/
dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
$scope,
$state,
$http,
config,
$window,
$translate,
ngToast) {
$scope.formdatastudent = { $scope.formdatastudent = {
"username": '', username: '',
"password": '', password: '',
"name": '', name: '',
"surname": '', surname: '',
"birthdate": '', birthdate: '',
"country": '', country: '',
"gender": 'F', gender: 'F',
"lang": 'es-es', lang: 'es-es',
"notes": '', notes: '',
"pic": "/app/img/default.jpg", pic: '/app/img/default.jpg',
"office": $scope.user.office || {name: ""} office: $scope.user.office || { name: '' }
}; };
//
// Flags for showing buttons according to role // Flags for showing buttons according to role
//
$scope.user = JSON.parse($window.sessionStorage.user); $scope.user = JSON.parse($window.sessionStorage.user);
if ($scope.user.office) { if ($scope.user.office) {
if ($scope.user.office.admin === $scope.user.id) // The user is administrator of the office if ($scope.user.office.admin === $scope.user.id) {
$scope.user.isAdmin = true; $scope.user.isAdmin = true;
}
if ($scope.user.office.currentStudents >= $scope.user.office.maxStudents) if ($scope.user.office.currentStudents >= $scope.user.office.maxStudents) {
$scope.num_licenses_left = 0; $scope.num_licenses_left = 0;
else } else {
$scope.num_licenses_left = $scope.user.office.maxStudents - $scope.user.office.currentStudents; $scope.num_licenses_left =
$scope.user.office.maxStudents -
$scope.user.office.currentStudents;
}
} else { } else {
$scope.user.office = {name: ""} $scope.user.office = { name: '' };
} }
//
// Get list of supervisor's students // Get list of supervisor's students
// $http.get(config.backend + '/sup/' + $scope.user.id + '/students')
$http .success(function (data) {
.get(config.backend+'/sup/' + $scope.user.id + '/students') $scope.students = data;
.success(function(data, status, headers, config) { })
// Add to list .error(function () {
$scope.students = data; // TODO show error with ngToast
console.log("Students listed:" + JSON.stringify(data)); });
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
// Reset form Student // Reset form Student
$scope.resetForm = function(){ $scope.resetForm = function () {
// Empty the form // Empty the form
$scope.formdatastudent = { $scope.formdatastudent = {
"username": '', username: '',
"password": '', password: '',
"password_confirm": '', password_confirm: '',
"name": '', name: '',
"surname": '', surname: '',
"birthdate": '', birthdate: '',
"country": '', country: '',
"gender": 'F', gender: 'F',
"lang": 'es-es', lang: 'es-es',
"notes": '', notes: '',
"pic": "/app/img/default.jpg", pic: '/app/img/default.jpg',
"office": $scope.user.office || {name: ""}, office: $scope.user.office || { name: '' },
"current_method": "no_method", current_method: 'no_method',
"current_instruction": "no_instruction" current_instruction: 'no_instruction'
}; };
// Hide the form // Hide the form
...@@ -75,41 +80,31 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl($scope, $s ...@@ -75,41 +80,31 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl($scope, $s
}; };
// Add Student // Add Student
$scope.add_student = function(){ $scope.add_student = function () {
var student = $scope.formdatastudent; var student = $scope.formdatastudent;
console.log(JSON.stringify(student));
// Validate password match // Validate password match
if(student.password_confirm.length && student.password != student.password_confirm) { if (student.password_confirm.length && student.password !== student.password_confirm) {
// ToDo: Highlight with Angular the input $translate('password_match').then(function (translation) {
$scope.showmessage = true; ngToast.danger({ content: translation });
$scope.alert = "alert-danger"; });
$scope.message = "password_match";
return; return;
} }
if (!student.password_confirm.length) { // password not changed (don't send it to DB) // password not changed (don't send it to DB)
if (!student.password_confirm.length) {
delete student.password; delete student.password;
delete student.password_confirm; delete student.password_confirm;
} }
$http.post(config.backend + '/stu', student)
$http .success(function (data) {
.post(config.backend+'/stu', student)
.success(function(data, status, headers, config) {
// Translate
$translate('student_added').then(function (translation) { $translate('student_added').then(function (translation) {
// Show message ngToast.success({ content: translation });
ngToast.success({ });
content: translation,
timeout: 6000 // By default 4000
});
});
// default values // default values
data.student.supervision = 0 // by default, only related to office administrator data.student.supervision = 0; // by default, only related to office administrator
data.student.current_method = 'no_method'; data.student.current_method = 'no_method';
data.student.current_instruction = 'no_instruction'; data.student.current_instruction = 'no_instruction';
...@@ -121,106 +116,57 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl($scope, $s ...@@ -121,106 +116,57 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl($scope, $s
$scope.resetForm(); $scope.resetForm();
// Show the add form to new adding // Show the add form to new adding
$scope.hidestudentadd = false; $scope.hidestudentadd = false;
console.log("Student added");
}) })
.error(function(data, status, headers, config) { .error(function (data) {
var errorMessage = 'student_not_added';
console.log("Error from API: " + JSON.stringify(data));
var msg = ""; if (data && data.raw && data.raw.sqlState && data.raw.sqlState === '20001') {
errorMessage = 'max_licenses_reached';
// Custom message for a generic error or for the maximum number of licenses reached by the office } else if (data && data.status === 400) {
if(data && data.raw && data.raw.sqlState && data.raw.sqlState == "20001") msg = "max_licenses_reached"; errorMessage = 'invalid_fields';
else if (data && data.status == 400) }
msg = "invalid_fields";
else
msg = "student_not_added";
// Translate
$translate(msg).then(function (translation) {
// Show message
ngToast.danger({
content: translation,
timeout: 6000 // By default 4000
});
});
$translate(errorMessage).then(function (translation) {
ngToast.danger({ content: translation });
});
}); });
}; };
// Delete Student // Delete Student
$scope.delete_student = function(student){ $scope.delete_student = function (student) {
var deleteStudent = $window.confirm('Are you absolutely sure you want to delete?'); var deleteStudent = $window.confirm('Are you absolutely sure you want to delete?');
if(deleteStudent){
$http
.delete(config.backend+'/stu/'+ student.id)
.success(function(data, status, headers, config) {
console.log("Student deleted:" + student.name);
// Eliminar de la vista: Se recorre el array de objetos json para buscarlo
for(var i=0; i < $scope.students.length; i++) {
if(student.id == $scope.students[i].id)
$scope.students.splice(i,1);
}
console.log("Student deleted:" + student.name);
// Translate if (deleteStudent) {
$http.delete(config.backend + '/stu/' + student.id)
.success(function () {
var i;
for (i = 0; i < $scope.students.length; i++) {
if (student.id === $scope.students[i].id) {
$scope.students.splice(i, 1);
}
}
$translate('student_deleted').then(function (translation) { $translate('student_deleted').then(function (translation) {
// Show message ngToast.success({ content: translation });
ngToast.success({ });
content: translation,
timeout: 6000 // By default 4000
});
});
// Empty the form
//$scope.resetForm();
}) })
.error(function(data, status, headers, config) { .error(function () {
console.log("Error deleting student from API: " + data.error);
//console.log("It could be students associated");
// Translate
$translate('student_not_deleted').then(function (translation) { $translate('student_not_deleted').then(function (translation) {
// Show message ngToast.danger({ content: translation });
ngToast.danger({ });
content: translation,
timeout: 6000 // By default 4000
});
});
}); });
//
// Due to a bug with http.delete, callback functions above are not
// called. So we do it again here until the bug is fixed.
//
// for(var i=0; i < $scope.students.length; i++) {
// if(student.id == $scope.students[i].id)
// $scope.students.splice(i,1);
// }
} }
}; };
////////////////////////////////////////////////////////// io.socket.post('/stu/unsubscribe', { action: 'unsubscribe' });
// Unsubscribe to student's socket room
io.socket.post('/stu/unsubscribe', {
action: 'unsubscribe'
},
function(res) {
console.log("Disconnected socket: " + res.msg);
});
//////////////////////////////////////////////////////////
}); });
//---------------------------------------------- /**
// Student Add Controller --> Only for calendar * StudentAddCtrl
//---------------------------------------------- */
dashboardControllers.controller('StudentAddCtrl', function StudentsCtrl($scope) { dashboardControllers.controller('StudentAddCtrl', function StudentsCtrl($scope) {
// Open calendar $scope.open_calendar = function ($event) {
$scope.open_calendar = function($event) { $event.preventDefault();
$event.preventDefault(); $event.stopPropagation();
$event.stopPropagation(); $scope.opened_cal_student = true;
};
$scope.opened_cal_student = true; });
};
});
\ No newline at end of file
...@@ -9,9 +9,6 @@ ...@@ -9,9 +9,6 @@
<!-- Formulario --> <!-- Formulario -->
<form name="setupForm" enctype="multipart/form-data" role="form" ng-submit="setup()"> <form name="setupForm" enctype="multipart/form-data" role="form" ng-submit="setup()">
<!-- Alert and success messages -->
<div ng-show="{{ 'showmessage' }}" class="alert" ng-class="alert" translate>{{message}}</div>
<!-- Change profile picture --> <!-- Change profile picture -->
<input type="file" ng-file-select="onFileSelect($files)" ng-model="picFile" accept="image/*"> <input type="file" ng-file-select="onFileSelect($files)" ng-model="picFile" accept="image/*">
...@@ -102,4 +99,3 @@ ...@@ -102,4 +99,3 @@
</div> </div>
<toast></toast>
<!-- StudentsCtrl controls here, see app.js --> <!-- StudentsCtrl controls here, see app.js -->
<div class="panel panel-default"> <div class="panel panel-default">
<!-- Default panel contents --> <!-- Default panel contents -->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment