Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
yotta
/
pictogram
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
60
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
f781c996
authored
Aug 10, 2017
by
Arturo Montejo Ráez
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Supervisor linking finished. New signup completed. Out cells in collections grid removed
parent
f588d2e8
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
305 additions
and
428 deletions
sails/src/api/controllers/StudentController.js
sails/src/api/controllers/SupervisorController.js
sails/src/api/models/Student.js
sails/src/api/policies/isStudentOrSupervisorOfStudent.js
sails/src/api/policies/isSupervisorOfStudent.js
sails/src/assets/app/i18n/en-gb.json
sails/src/assets/app/i18n/es-es.json
sails/src/assets/scripts/modules/student/controllers/setup.js
sails/src/assets/scripts/modules/student/controllers/student.js
sails/src/assets/scripts/modules/student/views/collections.html
sails/src/assets/scripts/modules/student/views/header.html
sails/src/assets/scripts/modules/student/views/setup.html
sails/src/assets/scripts/modules/supervisor/controllers/students.js
sails/src/assets/scripts/modules/supervisor/controllers/supervisors.js
sails/src/assets/scripts/modules/supervisor/views/instructions.html
sails/src/assets/scripts/modules/supervisor/views/students.html
sails/src/assets/scripts/modules/supervisor/views/students_add.html
sails/src/assets/scripts/modules/supervisor/views/supervisors_list.html
sails/src/config/locales/en-gb.json
sails/src/config/locales/es-es.json
sails/src/config/policies.js
sails/src/config/routes.js
sails/src/api/controllers/StudentController.js
View file @
f781c996
...
@@ -155,7 +155,7 @@ module.exports = {
...
@@ -155,7 +155,7 @@ module.exports = {
// Promisify asynchronous call to Student.supervisors
// Promisify asynchronous call to Student.supervisors
var
supervisors
=
new
Promise
(
function
(
resolve
,
reject
)
{
var
supervisors
=
new
Promise
(
function
(
resolve
,
reject
)
{
Student
.
supervisors
(
student
.
id
,
function
(
err
,
ss
)
{
Student
.
validSupervisors
(
student
.
id
,
req
.
token
.
id
,
function
(
err
,
ss
)
{
if
(
err
)
return
reject
(
err
);
if
(
err
)
return
reject
(
err
);
return
resolve
(
ss
);
return
resolve
(
ss
);
});
});
...
@@ -335,7 +335,7 @@ module.exports = {
...
@@ -335,7 +335,7 @@ module.exports = {
/**
/**
* Return all existing supervisor
and therapist from a given student
* Return all existing supervisor
s for a given student that are in our office
* @param {request} req {} (with studentId as url parameter)
* @param {request} req {} (with studentId as url parameter)
* @param {response} res
* @param {response} res
* [
* [
...
@@ -363,81 +363,12 @@ module.exports = {
...
@@ -363,81 +363,12 @@ module.exports = {
error
:
'No student defined'
error
:
'No student defined'
});
});
}
}
Student
.
supervisors
(
req
.
params
.
id_stu
,
function
(
err
,
sups
)
{
Student
.
validSupervisors
(
req
.
params
.
id_stu
,
req
.
token
.
id
,
function
(
err
,
sups
)
{
if
(
err
)
throw
err
;
if
(
err
)
throw
err
;
return
res
.
json
(
sups
);
return
res
.
json
(
sups
);
});
});
},
},
/**
* Return all existing therapists from a given student
* @param {request} req {} (with studentId as url parameter)
* @param {response} res
* [
* {
* id: therapistId,
* name: 'John',
* surname: 'Doe',
* gender: 'M/F',
* pic: 'supervisor/avatar.jpg',
* address: 'My Address, n1',
* country: 'ES',
* email: 'john@doe.es',
* phone: '+123123123',
* lang: 'es-es',
* active: true,
* ttsEngine: 'IVONA-Text',
* office: officeId
* },
* ...
* ]
*/
therapists
:
function
(
req
,
res
)
{
if
(
!
req
.
params
.
id_stu
)
{
return
res
.
json
(
500
,
{
error
:
'No student defined'
});
}
Student
.
therapists
(
req
.
params
.
id_stu
,
function
(
err
,
sups
)
{
if
(
err
)
throw
err
;
return
res
.
json
(
sups
);
});
},
/**
* Return all existing tutors from a given student
* @param {request} req {} (with studentId as url parameter)
* @param {response} res
* [
* {
* id: tutorId,
* name: 'John',
* surname: 'Doe',
* gender: 'M/F',
* pic: 'supervisor/avatar.jpg',
* address: 'My Address, n1',
* country: 'ES',
* email: 'john@doe.es',
* phone: '+123123123',
* lang: 'es-es',
* active: true,
* ttsEngine: 'IVONA-Text',
* office: officeId
* },
* ...
* ]
*/
tutors
:
function
(
req
,
res
)
{
if
(
!
req
.
params
.
id_stu
)
{
return
res
.
json
(
500
,
{
error
:
'No student defined'
});
}
Student
.
tutors
(
req
.
params
.
id_stu
,
function
(
err
,
sups
)
{
if
(
err
)
throw
err
;
return
res
.
json
(
sups
);
});
},
/**
/**
* Creates a relation between the student and a given supervisor.
* Creates a relation between the student and a given supervisor.
...
@@ -898,28 +829,27 @@ module.exports = {
...
@@ -898,28 +829,27 @@ module.exports = {
* @param {response} res {}
* @param {response} res {}
*/
*/
getActiveScene
:
function
(
req
,
res
){
getActiveScene
:
function
(
req
,
res
){
if
(
typeof
req
.
params
.
id_stu
==
'undefined'
||
!
req
.
params
.
id_stu
)
if
(
typeof
req
.
params
.
id_stu
==
'undefined'
||
!
req
.
params
.
id_stu
)
return
res
.
badRequest
(
"id_stu not defined"
);
return
res
.
badRequest
(
"id_stu not defined"
);
Student
.
findOne
({
id
:
req
.
params
.
id_stu
}).
then
(
function
(
student
){
Student
.
findOne
(
req
.
params
.
id_stu
)
Scene
.
findOne
({
id
:
student
.
id_active_scene
})
.
then
(
function
(
student
)
{
.
then
(
function
(
scene
){
if
(
!
student
)
if
(
!
scene
)
throw
new
Error
(
"Student not found"
)
return
res
.
badRequest
(
"Scene not found"
);
return
Scene
.
findOne
({
id
:
student
.
id_active_scene
});
else
})
Scene
.
pictos
(
scene
.
id
,
function
(
err
,
pictos
){
.
then
(
function
(
scene
){
if
(
err
){
if
(
!
scene
)
return
res
.
serverError
(
"Error obtaining pictos: "
+
err
);
throw
new
Error
(
"Scene not found"
);
}
Scene
.
pictos
(
scene
.
id
,
function
(
err
,
pictos
){
scene
.
active
=
true
;
if
(
err
)
scene
.
pictos
=
pictos
;
return
res
.
serverError
(
"Error obtaining pictos: "
+
err
);
return
res
.
ok
(
scene
);
scene
.
active
=
true
;
});
scene
.
pictos
=
pictos
;
}).
catch
(
function
(
err
){
return
res
.
ok
(
scene
);
return
res
.
serverError
(
"Error finding scene "
+
err
);
});
}).
catch
(
function
(
err
){
return
res
.
badRequest
(
"Student not found"
);
});
});
}).
catch
(
function
(
err
){
return
res
.
badRequest
(
err
.
message
);
});
},
},
/**
/**
...
...
sails/src/api/controllers/SupervisorController.js
View file @
f781c996
...
@@ -198,15 +198,54 @@ module.exports = {
...
@@ -198,15 +198,54 @@ module.exports = {
* }
* }
*/
*/
getByEmail
:
function
(
req
,
res
)
{
getByEmail
:
function
(
req
,
res
)
{
Supervisor
.
findOne
({
email
:
req
.
params
.
email
}).
then
(
function
(
supervisor
)
{
if
(
supervisor
)
{
// Find supervisor
res
.
ok
(
supervisor
);
Supervisor
.
findOne
({
email
:
req
.
params
.
email
})
}
else
{
.
then
((
s
)
=>
{
res
.
notFound
();
if
(
!
s
)
}
throw
new
Error
(
"Not found"
);
res
.
ok
(
s
);
})
})
.
catch
(
function
()
{
.
catch
(
function
(
err
)
{
res
.
serverError
();
res
.
serverError
(
err
);
});
},
/**
* Gets a supervisor by his email (only those that are related to us)
* @param {request} req {} (width email as url parameter)
* @param {response} res
* {
* "name": "John"
* "surname": "Doe"
* "gender": "F/M"
* "password": "1234"
* "pic": "url/to/photo.jpg"
* "address": "Nice street"
* "country": "ES/UK/..."
* "email": "john@doe.com"
* "phone": "+123456789"
* "lang": "ES/EN/..."
* "ttsEngine: "IVONA Text-to-Speech HQ"
* }
*/
getFromOfficeByEmail
:
function
(
req
,
res
)
{
// Find supervisor
Supervisor
.
findOne
({
email
:
req
.
params
.
email
})
.
then
((
s
)
=>
{
if
(
!
s
)
throw
new
Error
(
"Not found"
);
// Check is in our office
return
SupOff
.
findOne
({
supervisor
:
s
.
id
,
office
:
req
.
token
.
id
}).
populate
(
'supervisor'
);
})
.
then
((
so
)
=>
{
if
(
!
so
)
throw
new
Error
(
"Not in our office"
);
res
.
ok
(
so
.
supervisor
);
})
.
catch
(
function
(
err
)
{
res
.
serverError
(
err
);
});
});
},
},
...
@@ -512,19 +551,32 @@ module.exports = {
...
@@ -512,19 +551,32 @@ module.exports = {
// Check that both ids are valid
// Check that both ids are valid
Supervisor
.
findOne
(
req
.
params
.
id_sup
)
Supervisor
.
findOne
(
req
.
params
.
id_sup
)
.
then
((
s
)
=>
{
.
then
((
sup
)
=>
{
if
(
!
s
)
if
(
!
sup
)
throw
new
Error
(
"Supervisor not found"
);
return
Supervisor
.
findOne
(
req
.
params
.
id_off
);
}).
then
((
s
)
=>
{
if
(
!
s
)
throw
new
Error
(
"Supervisor not found"
);
throw
new
Error
(
"Supervisor not found"
);
return
SupOff
.
create
({
supervisor
:
req
.
params
.
id_sup
,
office
:
req
.
params
.
id_off
})
;
return
[
sup
,
Supervisor
.
findOne
(
req
.
params
.
id_off
)]
;
})
})
.
then
((
so
)
=>
{
.
spread
((
sup
,
off
)
=>
{
if
(
!
off
)
throw
new
Error
(
"Office not found"
);
return
[
sup
,
off
,
SupOff
.
create
({
supervisor
:
sup
.
id
,
office
:
off
.
id
})];
})
.
spread
((
sup
,
off
,
so
)
=>
{
if
(
!
so
)
if
(
!
so
)
throw
new
Error
(
"Unable to perform linking"
);
throw
new
Error
(
"Unable to perform linking"
);
res
.
ok
();
console
.
log
(
"SUP.LANG:"
+
sup
.
lang
);
// An notification is sent to added supervisor
mailService
.
mailer
()
.
send
({
to
:
sup
.
email
,
text
:
sails
.
__
({
phrase
:
'office_link'
,
locale
:
sup
.
lang
||
'es-es'
},
{
name
:
off
.
name
,
email
:
off
.
email
})
})
.
then
(()
=>
{
res
.
ok
()})
.
catch
((
err
)
=>
{
throw
err
});
})
})
.
catch
((
err
)
=>
{
.
catch
((
err
)
=>
{
res
.
badRequest
(
err
.
message
);
res
.
badRequest
(
err
.
message
);
...
...
sails/src/api/models/Student.js
View file @
f781c996
...
@@ -289,49 +289,56 @@ module.exports = {
...
@@ -289,49 +289,56 @@ module.exports = {
},
},
//
//
// Class method for getting the list of supervisors (therapist + tutors) associated to a given
// Class method for getting the list of supervisors associated to a given
// student
// student and where the requester is related office
supervisors
:
function
(
id_stu
,
callback
)
{
validSupervisors
:
function
(
id_stu
,
id_sup
,
callback
)
{
StuSup
.
find
({
id_stu
:
id_stu
}).
populate
(
'supervisor'
).
exec
(
function
(
err
,
stuSups
)
{
if
(
err
)
// Get all supervisors
return
callback
(
err
,
[]);
StuSup
.
find
({
id_stu
:
id_stu
})
.
populate
(
'supervisor'
)
.
then
((
stuSups
)
=>
{
if
(
!
stuSups
||
stuSups
.
length
==
0
)
if
(
!
stuSups
||
stuSups
.
length
==
0
)
return
callback
(
null
,
[]
);
throw
new
Error
(
"No supervisors"
);
// filter null entries and map them to the supervisor object
// return supervisors and related supervisors to the office
var
sups
=
_
.
compact
(
stuSups
).
map
((
st
)
=>
{
return
st
.
supervisor
});
return
[
stuSups
,
SupOff
.
find
({
office
:
id_sup
}).
populate
(
'supervisor'
)]
return
callback
(
null
,
sups
);
})
});
.
spread
((
stuSups
,
supOffs
)
=>
{
},
//
if
(
!
supOffs
||
supOffs
.
length
==
0
)
// Class method for getting the list of therapists associated to a given
throw
new
Error
(
"No supervisors"
);
// student
therapists
:
function
(
id_stu
,
callback
)
{
StuSup
.
find
({
id_stu
:
id_stu
}).
populate
(
'supervisor'
).
exec
(
function
(
err
,
stuSups
)
{
var
l
=
[];
if
(
err
||
!
stuSups
||
stuSups
.
length
==
0
)
// filter null entries and map them to the supervisor object
return
callback
(
err
,
l
);
var
ss
=
_
.
compact
(
_
.
compact
(
stuSups
).
map
(
x
=>
x
.
supervisor
));
var
so
=
_
.
compact
(
_
.
compact
(
supOffs
).
map
(
x
=>
x
.
supervisor
));
// filter from the second list those found in the first list
var
sups
=
so
.
filter
(
a
=>
ss
.
findIndex
(
b
=>
b
.
id
==
a
.
id
)
>=
0
);
var
sups
=
_
.
compact
(
stuSups
).
filter
((
st
)
=>
{
st
.
supervisor
&&
st
.
supervisor
.
role
==
'therapist'
});
return
callback
(
null
,
sups
);
return
callback
(
null
,
sups
);
})
.
catch
((
err
)
=>
{
return
callback
(
err
,
[]);
});
});
},
},
//
//
// Class method for getting the list of
tut
ors associated to a given
// Class method for getting the list of
all the supervis
ors associated to a given
// student
// student
tutors
:
function
(
id_stu
,
callback
)
{
allSupervisors
:
function
(
id_stu
,
callback
)
{
StuSup
.
find
({
id_stu
:
id_stu
}).
populate
(
'supervisor'
).
exec
(
function
(
err
,
stuSups
)
{
var
l
=
[];
if
(
err
||
!
stuSups
||
stuSups
.
length
==
0
)
return
callback
(
err
,
l
);
var
sups
=
_
.
compact
(
stuSups
).
filter
((
st
)
=>
{
st
.
supervisor
&&
st
.
supervisor
.
role
==
'tutor'
});
// Get all supervisors
return
callback
(
null
,
sups
);
StuSup
.
find
({
id_stu
:
id_stu
})
.
populate
(
'supervisor'
)
.
then
((
stuSups
)
=>
{
if
(
!
stuSups
||
stuSups
.
length
==
0
)
throw
new
Error
(
"No supervisors"
);
var
ss
=
_
.
compact
(
stuSups
).
map
(
x
=>
x
.
supervisor
);
return
callback
(
null
,
ss
);
})
.
catch
((
err
)
=>
{
return
callback
(
err
,
[]);
});
});
},
},
...
...
sails/src/api/policies/isStudentOrSupervisorOfStudent.js
View file @
f781c996
...
@@ -9,7 +9,7 @@ module.exports = function isStudentOrSupervisorOfStudent (req, res, next) {
...
@@ -9,7 +9,7 @@ module.exports = function isStudentOrSupervisorOfStudent (req, res, next) {
return
next
();
return
next
();
// Get list of supervisors for the student
// Get list of supervisors for the student
Student
.
s
upervisors
(
req
.
params
.
id_stu
,
function
(
err
,
sups
)
{
Student
.
allS
upervisors
(
req
.
params
.
id_stu
,
function
(
err
,
sups
)
{
if
(
err
)
if
(
err
)
return
res
.
json
(
401
,
{
error
:
err
});
return
res
.
json
(
401
,
{
error
:
err
});
...
...
sails/src/api/policies/isSupervisorOfStudent.js
View file @
f781c996
...
@@ -7,7 +7,7 @@ module.exports = function isSupervisorOfStudent(req, res, next) {
...
@@ -7,7 +7,7 @@ module.exports = function isSupervisorOfStudent(req, res, next) {
// Get list of supervisors for the student
// Get list of supervisors for the student
Student
.
s
upervisors
(
req
.
params
.
id_stu
,
function
(
err
,
sups
)
{
Student
.
allS
upervisors
(
req
.
params
.
id_stu
,
function
(
err
,
sups
)
{
if
(
err
)
if
(
err
)
return
res
.
json
(
401
,
{
error
:
err
});
return
res
.
json
(
401
,
{
error
:
err
});
...
...
sails/src/assets/app/i18n/en-gb.json
View file @
f781c996
...
@@ -419,7 +419,9 @@
...
@@ -419,7 +419,9 @@
"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"
,
"sup_not_in_office"
:
"There is no supervisor account related to your office/center with this email."
,
"supervisor_added"
:
"Supervisor added"
,
"supervisor_added"
:
"Supervisor added"
,
"supervisor_added_notified"
:
"Supervisor added. A notification email has been sent to his/her email address."
,
"supervisor_already_linked"
:
"The supervisor is already linked to your account"
,
"supervisor_already_linked"
:
"The supervisor is already linked to your account"
,
"supervisor_deleted"
:
"Supervisor deleted"
,
"supervisor_deleted"
:
"Supervisor deleted"
,
"supervisor_not_added"
:
"Supervisor not added"
,
"supervisor_not_added"
:
"Supervisor not added"
,
...
@@ -460,6 +462,7 @@
...
@@ -460,6 +462,7 @@
"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"
:
"Parent/tutor"
,
"tutor_added"
:
"Tutor added to the student"
,
"tutor_added"
:
"Tutor added to the student"
,
"tutor_account_desc"
:
"Manage child's pictograms and configure his/her communication device."
,
"tutor_account_desc"
:
"Manage child's pictograms and configure his/her communication device."
,
"tutor_deleted"
:
"Tutor removed from the student"
,
"tutor_deleted"
:
"Tutor removed from the student"
,
...
...
sails/src/assets/app/i18n/es-es.json
View file @
f781c996
...
@@ -79,8 +79,7 @@
...
@@ -79,8 +79,7 @@
"close_session"
:
"Cerrar sesion"
,
"close_session"
:
"Cerrar sesion"
,
"collections"
:
"Colecciones"
,
"collections"
:
"Colecciones"
,
"confirmation"
:
"¿Estás seguro?"
,
"confirmation"
:
"¿Estás seguro?"
,
"confirm_unlink_therapist"
:
"¿Desligar {{ name }} de {{ student }} como terapeuta?"
,
"confirm_unlink_student"
:
"¿Desligar {{ name }} de {{ student }}?"
,
"confirm_unlink_tutor"
:
"¿Desligar {{ name }} de {{ student }} como tutor?"
,
"contact_person"
:
"Persona de contacto"
,
"contact_person"
:
"Persona de contacto"
,
"contact_person"
:
"Persona de contacto"
,
"contact_person"
:
"Persona de contacto"
,
"continue_session"
:
"Reanudar sesión"
,
"continue_session"
:
"Reanudar sesión"
,
...
@@ -263,7 +262,8 @@
...
@@ -263,7 +262,8 @@
"no_method"
:
"Método sin definir"
,
"no_method"
:
"Método sin definir"
,
"no_office"
:
"Sin centro"
,
"no_office"
:
"Sin centro"
,
"no_instruction"
:
"Instrucción sin definir"
,
"no_instruction"
:
"Instrucción sin definir"
,
"no_students_for_user"
:
"Su cuenta no está asociada a ningún estudiante. Por favor, contacte con su gabinete para enlazar su cuenta a un estudiante."
,
"no_students"
:
"Su cuenta no está asociada a ningún estudiante"
,
"no_students_desc"
:
"Pulse en 'Añadir estudiante' para vincularse a cuentas de alumnos existentes o dar de alta nuevas"
,
"no_space_in_category"
:
"No queda espacio en la categoría"
,
"no_space_in_category"
:
"No queda espacio en la categoría"
,
"no_subscribed"
:
"Sin conexión a la cuenta del estudiante"
,
"no_subscribed"
:
"Sin conexión a la cuenta del estudiante"
,
"no_supervisors"
:
"No tiene tutores, padres o terapeutas asociados."
,
"no_supervisors"
:
"No tiene tutores, padres o terapeutas asociados."
,
...
@@ -419,7 +419,9 @@
...
@@ -419,7 +419,9 @@
"sup_not_added"
:
"El supervisor no se ha podido añadir al estudiante."
,
"sup_not_added"
:
"El supervisor no se ha podido añadir al estudiante."
,
"sup_not_deleted"
:
"El supervisor no se ha podido desvincular del alumno."
,
"sup_not_deleted"
:
"El supervisor no se ha podido desvincular del alumno."
,
"sup_not_found"
:
"No hay ningún usuario en Pictogram con ese correo electrónico."
,
"sup_not_found"
:
"No hay ningún usuario en Pictogram con ese correo electrónico."
,
"sup_not_in_office"
:
"No hay ningún usuario asociado a su centro/gabinete con ese correo electrónico."
,
"supervisor_added"
:
"Supervisor añadido"
,
"supervisor_added"
:
"Supervisor añadido"
,
"supervisor_added_notified"
:
"Supervisor añadido. Se le ha enviado al mismo una notificación por correo electrónico."
,
"supervisor_already_linked"
:
"El supervisor ya está vinculado"
,
"supervisor_already_linked"
:
"El supervisor ya está vinculado"
,
"supervisor_deleted"
:
"Supervisor eliminado"
,
"supervisor_deleted"
:
"Supervisor eliminado"
,
"supervisor_not_added"
:
"Supervisor no añadido"
,
"supervisor_not_added"
:
"Supervisor no añadido"
,
...
@@ -460,6 +462,7 @@
...
@@ -460,6 +462,7 @@
"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"
:
"Padre/madre/tutor"
,
"tutor_account_desc"
:
"Gestione los pictogramas de su hijo o hija y configure su dispositivo de comunicación."
,
"tutor_account_desc"
:
"Gestione los pictogramas de su hijo o hija y configure su dispositivo de comunicación."
,
"tutor_added"
:
"Tutor añadido al estudiante"
,
"tutor_added"
:
"Tutor añadido al estudiante"
,
"tutor_deleted"
:
"Tutor desvinculado del estudiante"
,
"tutor_deleted"
:
"Tutor desvinculado del estudiante"
,
...
...
sails/src/assets/scripts/modules/student/controllers/setup.js
View file @
f781c996
...
@@ -26,7 +26,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -26,7 +26,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
});*/
});*/
$scope
.
supsForm
=
{};
$scope
.
supsForm
=
{};
$scope
.
section
=
'account'
;
$scope
.
section
=
{
val
:
'account'
}
;
$scope
.
changeImg
=
function
()
{
$scope
.
changeImg
=
function
()
{
...
@@ -148,11 +148,11 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -148,11 +148,11 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
.
error
(
function
(
err
)
{
.
error
(
function
(
err
)
{
console
.
log
(
err
);
console
.
log
(
err
);
if
(
err
.
message
&&
err
.
message
.
search
(
'nvalid license'
)
>
0
)
if
(
err
.
message
&&
err
.
message
.
search
(
'nvalid license'
)
>
0
)
ngToast
.
danger
(
{
content
:
$translate
.
instant
(
'license_invalid'
)
}
);
ngToast
.
danger
(
$translate
.
instant
(
'license_invalid'
)
);
else
if
(
err
.
message
&&
err
.
message
.
search
(
'in use'
)
>
0
)
else
if
(
err
.
message
&&
err
.
message
.
search
(
'in use'
)
>
0
)
ngToast
.
danger
(
{
content
:
$translate
.
instant
(
'license_already_activated'
)
}
);
ngToast
.
danger
(
$translate
.
instant
(
'license_already_activated'
)
);
else
else
ngToast
.
danger
(
{
content
:
$translate
.
instant
(
'student_not_updated'
)
}
);
ngToast
.
danger
(
$translate
.
instant
(
'student_not_updated'
)
);
});
});
};
};
...
@@ -161,26 +161,21 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -161,26 +161,21 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
* The email used for search is fetched from $scope.email_sup.
* The email used for search is fetched from $scope.email_sup.
*/
*/
$scope
.
search_sup
=
function
()
{
$scope
.
search_sup
=
function
()
{
console
.
log
(
"--> "
+
$scope
.
supsForm
.
email_sup
);
// Find tutor by email
// Find tutor by email
$http
.
get
(
config
.
backend
+
'/sup/email/'
+
$scope
.
supsForm
.
email_sup
)
$http
.
get
(
config
.
backend
+
'/sup/
off/
email/'
+
$scope
.
supsForm
.
email_sup
)
.
success
(
function
(
data
)
{
.
success
(
function
(
data
)
{
if
(
data
)
{
if
(
data
)
{
$scope
.
supToAdd
=
data
;
$scope
.
supToAdd
=
data
;
$scope
.
showmessagesupfound
=
true
;
$scope
.
showmessagesupfound
=
true
;
$scope
.
showmessagesupnotfound
=
false
;
$scope
.
showmessagesupnotfound
=
false
;
}
else
{
}
else
{
$translate
(
'sup_not_found'
).
then
(
function
(
translation
)
{
ngToast
.
danger
(
$translate
.
instant
(
'sup_not_in_office'
));
ngToast
.
danger
({
content
:
translation
});
});
// 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
()
{
.
error
(
function
()
{
$translate
(
'sup_not_found'
).
then
(
function
(
translation
)
{
ngToast
.
danger
(
$translate
.
instant
(
'sup_not_in_office'
));
ngToast
.
danger
({
content
:
translation
});
});
});
});
};
};
...
@@ -193,13 +188,13 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -193,13 +188,13 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
// Ensure supervisor is not already in the list
// Ensure supervisor is not already in the list
if
(
$scope
.
studentSupervisors
.
map
((
s
)
=>
s
.
id
).
includes
(
$scope
.
supToAdd
.
id
))
{
if
(
$scope
.
studentSupervisors
.
map
((
s
)
=>
s
.
id
).
includes
(
$scope
.
supToAdd
.
id
))
{
ngToast
.
danger
(
{
content
:
$translate
.
instant
(
'sup_already_added'
)
}
);
ngToast
.
danger
(
$translate
.
instant
(
'sup_already_added'
)
);
$scope
.
supsForm
.
email_sup
=
''
;
$scope
.
supsForm
.
email_sup
=
''
;
$scope
.
showmessagesupfound
=
false
;
$scope
.
showmessagesupfound
=
false
;
return
;
return
;
}
}
$http
.
post
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
+
'/sup/'
+
$scope
.
supToAdd
.
id
,
{
asTherapist
:
true
}
)
$http
.
post
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
+
'/sup/'
+
$scope
.
supToAdd
.
id
)
.
success
(
function
(
data
)
{
.
success
(
function
(
data
)
{
// Assign the info of supervisor to add
// Assign the info of supervisor to add
stusup
.
supervisor
=
$scope
.
supToAdd
;
stusup
.
supervisor
=
$scope
.
supToAdd
;
...
@@ -214,7 +209,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -214,7 +209,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
$scope
.
showmessagesupfound
=
false
;
$scope
.
showmessagesupfound
=
false
;
})
})
.
error
(
function
()
{
.
error
(
function
()
{
ngToast
.
danger
(
{
content
:
$translate
.
instant
(
'sup_not_added'
)
}
);
ngToast
.
danger
(
$translate
.
instant
(
'sup_not_added'
)
);
});
});
};
};
...
@@ -226,7 +221,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -226,7 +221,7 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
var
deleteSup
=
$window
.
confirm
(
var
deleteSup
=
$window
.
confirm
(
$translate
.
instant
(
$translate
.
instant
(
'confirm_unlink_
therapis
t'
,
'confirm_unlink_
studen
t'
,
{
name
:
$scope
.
studentSupervisors
[
i
].
name
,
student
:
$scope
.
studentData
.
name
}
{
name
:
$scope
.
studentSupervisors
[
i
].
name
,
student
:
$scope
.
studentData
.
name
}
));
));
...
@@ -243,95 +238,6 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -243,95 +238,6 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
}
}
};
};
// Search tutor by email
$scope
.
search_tutor
=
function
()
{
// Find tutor by email
$http
.
get
(
config
.
backend
+
'/sup/email/'
+
$scope
.
supsForm
.
email_tutor
)
.
success
(
function
(
data
)
{
// If it found the length is > 0
if
(
data
)
{
$scope
.
tutorToAdd
=
data
;
// Show message for validate
$scope
.
showmessagetutorfound
=
true
;
$scope
.
showmessagetutornotfound
=
false
;
}
else
{
$translate
(
'tutor_not_found'
).
then
(
function
(
translation
)
{
ngToast
.
danger
({
content
:
translation
});
});
// Hide the success message (if it exists by other query)
$scope
.
showmessagetutorfound
=
false
;
}
})
.
error
(
function
()
{
$translate
(
'tutor_not_found'
).
then
(
function
(
translation
)
{
ngToast
.
danger
({
content
:
translation
});
});
});
};
// Add tutor
$scope
.
add_tutor
=
function
()
{
var
stusup
=
{
student
:
$scope
.
studentData
.
id
,
supervisor
:
$scope
.
tutorToAdd
.
id
};
// Ensure supervisor is not already in the list
if
(
$scope
.
studentTutors
.
map
((
s
)
=>
s
.
id
).
includes
(
$scope
.
tutorToAdd
.
id
))
{
ngToast
.
danger
({
content
:
$translate
.
instant
(
'sup_already_added'
)
});
$scope
.
supsForm
.
email_tutor
=
''
;
$scope
.
showmessagetutorfound
=
false
;
return
;
}
$http
.
post
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
+
'/sup/'
+
$scope
.
tutorToAdd
.
id
)
.
success
(
function
(
data
)
{
// Assign the info of supervisor to add
stusup
.
supervisor
=
$scope
.
tutorToAdd
;
stusup
.
id
=
data
.
id
;
// Add to the list of tutors in view
$scope
.
studentTutors
.
push
(
$scope
.
tutorToAdd
);
// Delete the email form field
$scope
.
supsForm
.
email_tutor
=
''
;
// Hide the message of tutor founded
$scope
.
showmessagetutorfound
=
false
;
$translate
(
'tutor_added'
).
then
(
function
(
translation
)
{
ngToast
.
success
({
content
:
translation
});
});
})
.
error
(
function
()
{
$translate
(
'tutor_not_added'
).
then
(
function
(
translation
)
{
ngToast
.
danger
({
content
:
translation
});
});
});
};
// Delete tutor
$scope
.
delete_tutor
=
function
(
id_sup
)
{
//Se recorre el array de objetos json para buscarlo
var
i
;
for
(
i
=
0
;
i
<
$scope
.
studentTutors
.
length
&&
id_sup
!==
$scope
.
studentTutors
[
i
].
id
;
i
++
);
var
deleteTutor
=
$window
.
confirm
(
$translate
.
instant
(
'confirm_unlink_tutor'
,
{
name
:
$scope
.
studentTutors
[
i
].
name
,
student
:
$scope
.
studentData
.
name
}
));
if
(
deleteTutor
)
{
$http
.
delete
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
+
'/sup/'
+
id_sup
)
.
success
(
function
()
{
// Eliminar de la vista
$scope
.
studentTutors
.
splice
(
i
,
1
);
ngToast
.
success
({
content
:
$translate
.
instant
(
'tutor_deleted'
)
});
})
.
error
(
function
()
{
ngToast
.
danger
({
content
:
$translate
.
instant
(
'tutor_not_deleted'
)
});
});
}
};
// *******************************************************
// *******************************************************
// Setup
// Setup
// $scope.studentData.attributes
// $scope.studentData.attributes
...
@@ -342,14 +248,10 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
...
@@ -342,14 +248,10 @@ dashboardControllers.controller('StudentSetupCtrl', function StudentSetupCtrl(
attributes
:
$scope
.
studentData
.
attributes
attributes
:
$scope
.
studentData
.
attributes
})
})
.
success
(
function
()
{
.
success
(
function
()
{
$translate
(
'attributes_updated'
).
then
(
function
(
translation
)
{
ngToast
.
success
(
$translate
.
instant
(
'attributes_updated'
));
ngToast
.
success
({
content
:
translation
});
});
})
})
.
error
(
function
()
{
.
error
(
function
()
{
$translate
(
'attributes_not_updated'
).
then
(
function
(
translation
)
{
ngToast
.
danger
(
$translate
.
instant
(
'attributes_not_updated'
));
ngToast
.
danger
({
content
:
translation
});
});
});
});
},
300
);
},
300
);
});
});
sails/src/assets/scripts/modules/student/controllers/student.js
View file @
f781c996
...
@@ -83,11 +83,11 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl(
...
@@ -83,11 +83,11 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl(
};
};
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// MAIN
//
//
// Load student account information
// Load student account information
//
//
//
$http
.
get
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
)
$http
.
get
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
)
.
success
(
function
(
data
)
{
.
success
(
function
(
data
)
{
$scope
.
studentData
.
id
=
data
.
id
;
$scope
.
studentData
.
id
=
data
.
id
;
...
@@ -141,27 +141,22 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl(
...
@@ -141,27 +141,22 @@ dashboardControllers.controller('StudentCtrl', function StudentCtrl(
ngToast
.
danger
({
content
:
$translate
.
instant
(
'no_subscribed'
)
});
ngToast
.
danger
({
content
:
$translate
.
instant
(
'no_subscribed'
)
});
});
});
//
// 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'
};
};
//
// Load student supervisors
//
$scope
.
studentSupervisors
=
[];
$scope
.
studentSupervisors
=
[];
$http
.
get
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
+
'/
therapist
s'
)
$http
.
get
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
+
'/
supervisor
s'
)
.
success
(
function
(
data
)
{
.
success
(
function
(
data
)
{
$scope
.
studentSupervisors
=
data
;
$scope
.
studentSupervisors
=
data
;
})
})
.
error
(
function
()
{
.
error
(
function
(
err
)
{});
// TODO show error with ngToast
});
$scope
.
studentTutors
=
[];
$http
.
get
(
config
.
backend
+
'/stu/'
+
$scope
.
studentData
.
id
+
'/tutors'
)
.
success
(
function
(
data
)
{
$scope
.
studentTutors
=
data
;
})
.
error
(
function
()
{
// TODO show error with ngToast
});
});
});
sails/src/assets/scripts/modules/student/views/collections.html
View file @
f781c996
...
@@ -25,7 +25,8 @@
...
@@ -25,7 +25,8 @@
ng-init=
"rowIndex = $index"
ng-init=
"rowIndex = $index"
class=
"picto-grid__row"
>
class=
"picto-grid__row"
>
<div
<div
class=
"picto pull-left ng-class:{'picto-out': studentData.attributes.size == 'large' && (rowIndex > 3 || colIndex > 7)};"
ng-hide=
"studentData.attributes.size == 'large' && (rowIndex > 3 || colIndex > 7)"
class=
"picto pull-left"
data-row=
"{{ rowIndex }}"
data-row=
"{{ rowIndex }}"
data-column=
"{{ colIndex }}"
data-column=
"{{ colIndex }}"
id=
"student-picto-{{
id=
"student-picto-{{
...
@@ -117,7 +118,8 @@
...
@@ -117,7 +118,8 @@
ng-init=
"rowIndex = $index"
ng-init=
"rowIndex = $index"
class=
"picto-grid__row"
>
class=
"picto-grid__row"
>
<div
<div
class=
"picto pull-left ng-class:{'picto-out': studentData.attributes.size == 'large' && (rowIndex > 3 || colIndex > 7)};"
ng-hide=
"studentData.attributes.size == 'large' && (rowIndex > 3 || colIndex > 7)"
class=
"picto pull-left"
ng-repeat=
"studentPicto in studentPictoRow track by $index"
ng-repeat=
"studentPicto in studentPictoRow track by $index"
ng-init=
"colIndex = $index"
ng-init=
"colIndex = $index"
popover=
"{{ studentPicto != emptyStudentPicto ? studentPicto.attributes.expression : ''}}"
popover=
"{{ studentPicto != emptyStudentPicto ? studentPicto.attributes.expression : ''}}"
...
@@ -231,7 +233,8 @@
...
@@ -231,7 +233,8 @@
ng-init=
"rowIndex = $index"
ng-init=
"rowIndex = $index"
class=
"picto-grid__row"
>
class=
"picto-grid__row"
>
<div
<div
class=
"picto pull-left ng-class:{'picto-out': studentData.attributes.size == 'large' && (rowIndex > 3 || colIndex > 7)};"
ng-hide=
"studentData.attributes.size == 'large' && (rowIndex > 3 || colIndex > 7)"
class=
"picto pull-left"
data-row=
"{{ rowIndex }}"
data-row=
"{{ rowIndex }}"
data-column=
"{{ colIndex }}"
data-column=
"{{ colIndex }}"
id=
"student-picto-{{
id=
"student-picto-{{
...
...
sails/src/assets/scripts/modules/student/views/header.html
View file @
f781c996
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
<div
class=
"col-md-12"
>
<div
class=
"col-md-12"
>
<ul
class=
"nav nav-tabs tabs_student"
>
<ul
class=
"nav nav-tabs tabs_student"
>
<!-- 0: admin, 1: tutor, 2: therapist -->
<!-- 0: admin, 1: tutor, 2: therapist -->
<li
role=
"presentation"
ng-class=
"{'active' : nav.tab == 'collections'}"
ng-if=
"studentData.license.isValid
&&
!studentData.license.isTrial"
>
<li
role=
"presentation"
ng-class=
"{'active' : nav.tab == 'collections'}"
ng-if=
"studentData.license.isValid
||
!studentData.license.isTrial"
>
<a
href=
"/app/#/student/{{studentData.id}}/collections"
ng-click=
"nav.tab = ''"
><span
class=
"glyphicon glyphicon-th"
aria-hidden=
"true"
></span>
{{ 'collections' | translate }}
</a>
<a
href=
"/app/#/student/{{studentData.id}}/collections"
ng-click=
"nav.tab = ''"
><span
class=
"glyphicon glyphicon-th"
aria-hidden=
"true"
></span>
{{ 'collections' | translate }}
</a>
</li>
</li>
<li
role=
"presentation"
ng-class=
"{'active' : nav.tab == 'instructions'}"
ng-if=
"studentData.license.isValid && !user.isTutor"
>
<li
role=
"presentation"
ng-class=
"{'active' : nav.tab == 'instructions'}"
ng-if=
"studentData.license.isValid && !user.isTutor"
>
...
...
sails/src/assets/scripts/modules/student/views/setup.html
View file @
f781c996
...
@@ -2,18 +2,21 @@
...
@@ -2,18 +2,21 @@
<div
class=
"panel-body"
>
<div
class=
"panel-body"
>
<div
class=
"btn-group"
>
<div
class=
"btn-group"
>
<button
class=
"btn btn-default"
btn-radio=
"'account'"
ng-model=
"section"
>
<button
class=
"btn btn-default"
btn-radio=
"'account'"
ng-model=
"section
.val
"
>
<i
class=
"fa fa-user"
aria-hidden=
"true"
></i>
{{ 'account' | translate }}
<i
class=
"fa fa-user"
aria-hidden=
"true"
></i>
{{ 'account' | translate }}
</button>
</button>
<button
class=
"btn btn-default"
btn-radio=
"'device'"
ng-model=
"section"
ng-if=
"studentData.license.isValid || studentData.license.isOfficial"
>
<button
class=
"btn btn-default"
btn-radio=
"'device'"
ng-model=
"section
.val
"
ng-if=
"studentData.license.isValid || studentData.license.isOfficial"
>
<i
class=
"fa fa-tablet"
aria-hidden=
"true"
></i>
{{ 'device' | translate }}
<i
class=
"fa fa-tablet"
aria-hidden=
"true"
></i>
{{ 'device' | translate }}
</button>
</button>
<button
class=
"btn btn-default"
btn-radio=
"'supervisors'"
ng-model=
"section"
ng-if=
"user.isOffice"
>
<button
class=
"btn btn-default"
btn-radio=
"'supervisors'"
ng-model=
"section
.val
"
ng-if=
"user.isOffice"
>
<i
class=
"fa fa-users"
aria-hidden=
"true"
></i>
{{ 'supervisors' | translate }}
<i
class=
"fa fa-users"
aria-hidden=
"true"
></i>
{{ 'supervisors' | translate }}
</button>
</button>
</div>
</div>
<div
class=
"row"
ng-show=
"section == 'account'"
>
<!-- ***********************************************************************
Sección: Configuración de la cuenta del estudiante
-->
<div
class=
"row"
ng-show=
"section.val == 'account'"
>
<!-- Parte izquierda: Datos personales -->
<!-- Parte izquierda: Datos personales -->
<div
class=
"col-md-6"
>
<div
class=
"col-md-6"
>
<legend
translate
>
account
</legend>
<legend
translate
>
account
</legend>
...
@@ -187,9 +190,12 @@
...
@@ -187,9 +190,12 @@
</div>
<!-- Fin de student_personal_edit -->
</div>
<!-- Fin de student_personal_edit -->
<!-- ***********************************************************************
Sección: Configuración del dispositivo
-->
<!-- Configuración dispositivo -->
<!-- Configuración dispositivo -->
<div
id=
"device_setup"
ng-show=
"section == 'device'"
>
<div
id=
"device_setup"
ng-show=
"section
.val
== 'device'"
>
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-md-6"
>
<div
class=
"col-md-6"
>
<legend
translate
>
device_setup
</legend>
<legend
translate
>
device_setup
</legend>
...
@@ -325,14 +331,28 @@
...
@@ -325,14 +331,28 @@
</div>
</div>
</div>
</div>
<!-- ***********************************************************************
Sección: Gestión de supervisores
-->
<!-- Tutores y dispositivos -->
<!-- Tutores y dispositivos -->
<div
id=
"supervisors_section"
ng-show=
"section == 'supervisors'"
>
<div
id=
"supervisors_section"
ng-show=
"section.val == 'supervisors'"
ng-if=
"user.isOffice"
>
<legend
translate
>
link_supervisor
</legend>
<div
class=
"row"
>
<div
class=
"row"
>
<div
class=
"col-md-5"
ng-if=
"user.isOffice"
>
<div
class=
"col-md-5"
>
<div
class=
"alert alert-info"
>
<p
translate
>
link_supervisor_desc
</p>
<p
translate
>
supervisor_note
</p>
</div>
</div>
<div
class=
"col-md-5"
>
<!-- Supervisores (terapeutas) del alumno -->
<!-- Supervisores (terapeutas) del alumno -->
<div
id=
"student_sups"
>
<div
id=
"student_sups"
>
<legend
translate
>
therapists
</legend>
<!-- Buscador de supervisores -->
<!-- Buscador de supervisores -->
<p>
<p>
<form
role=
"search"
ng-submit=
"search_sup()"
>
<form
role=
"search"
ng-submit=
"search_sup()"
>
...
@@ -353,71 +373,34 @@
...
@@ -353,71 +373,34 @@
<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-sm pull-right"
role=
"button"
ng-click=
"add_sup()"
translate
>
add
</a>
<a
class=
"btn btn-default btn-sm pull-right"
role=
"button"
ng-click=
"add_sup()"
translate
>
add
</a>
</div>
</div>
<!-- Fin de buscador de supervisores -->
<!-- Supervisores asignados -->
<!-- Supervisores asignados -->
<ul
class=
"list-group"
id=
"user_sups"
>
<ul
class=
"list-group"
id=
"user_sups"
>
<li
class=
"list-group-item"
ng-repeat=
"sup in studentSupervisors"
>
<li
class=
"list-group-item"
ng-repeat=
"sup in studentSupervisors"
>
<!-- Imagen de perfil del supervisor -->
<div
class=
"row"
>
<img
ng-src=
"{{sup.pic}}"
class=
"profile"
alt=
""
title=
""
/>
<div
class=
"col-xs-2"
>
{{sup.name}} {{sup.surname}}
<!-- Imagen de perfil del supervisor -->
<a
ng-click=
"delete_sup(sup.id)"
class=
"delete_sup"
title=
"{{ 'unlink' | translate}}"
>
<img
ng-src=
"{{sup.pic}}"
class=
"profile"
alt=
""
title=
""
/>
<span
class=
"color_red glyphicon glyphicon-remove-circle"
aria-hidden=
"true"
></span>
</div>
</a>
<div
class=
"col-xs-8"
>
</li>
{{ sup.name }} {{ sup.surname }}
<br>
<span
class=
"text-muted"
>
{{ sup.role | translate }}
</span>
</ul>
</div>
<!-- Fin de Supervisores asignados -->
<div
class=
"col-xs-2"
>
</div>
<a
ng-click=
"delete_sup(sup.id)"
class=
"delete_sup"
title=
"{{ 'unlink' | translate}}"
>
<!-- Fin de id student-sups -->
<span
class=
"color_red glyphicon glyphicon-remove-circle"
aria-hidden=
"true"
></span>
</div>
</a>
<div
class=
"col-md-5"
>
<!-- Tutores (Padres) -->
<div
id=
"student_tutors"
ng-if=
"user.isOffice"
>
<legend
translate
>
tutors
</legend>
<!-- Buscador de tutores -->
<p>
<form
role=
"search"
ng-submit=
"search_tutor()"
>
<div
class=
"input-group"
>
<input
type=
"email"
class=
"form-control"
placeholder=
"{{ 'search_tutor_email' | translate }}"
name=
"email_tutor"
id=
"email_tutor"
ng-model=
"supsForm.email_tutor"
required
>
<div
class=
"input-group-btn"
>
<button
class=
"btn btn-default"
type=
"submit"
>
<span
class=
"glyphicon glyphicon-search"
></span>
</button>
</div>
</div>
</div>
</div>
</form>
</p>
<!-- Alert and success messages for tutor found -->
<div
ng-show=
"{{ 'showmessagetutorfound' }}"
class=
"alert alert-info"
>
<!-- Imagen de perfil del tutor -->
<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>
</div>
<!-- Fin de buscador de tutores -->
<!-- Tutores asignados -->
<ul
class=
"list-group"
id=
"user_tutors"
>
<li
class=
"list-group-item"
ng-repeat=
"tutor in studentTutors"
>
<!-- Imagen de perfil del tutor -->
<img
ng-src=
"{{tutor.pic}}"
class=
"profile"
alt=
""
title=
""
/>
{{tutor.name}} {{tutor.surname}}
<a
ng-click=
"delete_tutor(tutor.id)"
class=
"delete_tutor"
title=
"{{ 'unlink' | translate}}"
>
<span
class=
"color_red glyphicon glyphicon-remove-circle"
aria-hidden=
"true"
></span>
</a>
</li>
</li>
</ul>
</ul>
<!-- Fin de Tutores asignados -->
<!-- Fin de Supervisores asignados -->
<!-- Info message -->
<div
class=
"alert alert-info"
>
{{ 'supervisor_note' | translate }}
</div>
</div>
</div>
<!-- Fin de id student-
tutor
s -->
<!-- Fin de id student-
sup
s -->
</div>
</div>
</div>
</div>
</div>
<!-- /supervisores -->
</div>
<!-- /supervisores -->
</div>
</div>
<!-- Fin de panel body -->
<!-- Fin de panel body -->
</div>
</div>
...
...
sails/src/assets/scripts/modules/supervisor/controllers/students.js
View file @
f781c996
...
@@ -56,13 +56,6 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
...
@@ -56,13 +56,6 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
}
}
};
};
// calendar function
$scope
.
open_calendar
=
function
(
$event
)
{
$event
.
preventDefault
();
$event
.
stopPropagation
();
$scope
.
opened_cal_student
=
true
;
};
// Show student form
// Show student form
$scope
.
showForm
=
function
()
{
$scope
.
showForm
=
function
()
{
// Reset the form
// Reset the form
...
@@ -103,14 +96,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
...
@@ -103,14 +96,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
// Send link call to server
// Send link call to server
$http
.
post
(
config
.
backend
+
'/stu/license/sup/'
+
$scope
.
user
.
id
,
{
license
:
$scope
.
formdata
.
license_number
})
$http
.
post
(
config
.
backend
+
'/stu/license/sup/'
+
$scope
.
user
.
id
,
{
license
:
$scope
.
formdata
.
license_number
})
.
success
(
function
(
data
)
{
.
success
(
function
(
data
)
{
ngToast
.
success
({
content
:
$translate
.
instant
(
'student_added'
)
});
loadStudents
();
// default values
data
.
current_method
=
$translate
.
instant
(
'no_method'
);
data
.
current_instruction
=
$translate
.
instant
(
'no_instruction'
);
data
.
licenseIsValid
=
new
Date
(
data
.
license
.
expiration_ts
)
-
new
Date
()
>
0
?
true
:
false
;
$scope
.
students
.
push
(
data
);
$scope
.
slide
.
rightTo
(
'confirmation'
);
$scope
.
slide
.
rightTo
(
'confirmation'
);
})
})
.
error
(
function
(
err
)
{
.
error
(
function
(
err
)
{
...
@@ -146,15 +132,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
...
@@ -146,15 +132,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
// Send creating call to server
// Send creating call to server
$http
.
post
(
config
.
backend
+
'/stu'
,
$scope
.
formdata
)
$http
.
post
(
config
.
backend
+
'/stu'
,
$scope
.
formdata
)
.
success
(
function
(
data
)
{
.
success
(
function
(
data
)
{
ngToast
.
success
({
content
:
$translate
.
instant
(
'student_added'
)
});
loadStudents
();
// default values
data
.
supervision
=
0
;
// by default, only related to office administrator
data
.
current_method
=
$translate
.
instant
(
'no_method'
);
data
.
current_instruction
=
$translate
.
instant
(
'no_instruction'
);
data
.
licenseIsValid
=
new
Date
(
data
.
license
.
expiration_ts
)
-
new
Date
()
>
0
?
true
:
false
;
$scope
.
students
.
push
(
data
);
$scope
.
slide
.
rightTo
(
'confirmation'
);
$scope
.
slide
.
rightTo
(
'confirmation'
);
})
})
.
error
(
function
(
err
)
{
.
error
(
function
(
err
)
{
...
@@ -179,14 +157,16 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
...
@@ -179,14 +157,16 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
// Students list
// Students list
// --------------------------------------------------------
// --------------------------------------------------------
// Get list of supervisor's students
function
loadStudents
()
{
$http
.
get
(
config
.
backend
+
'/sup/'
+
$scope
.
user
.
id
+
'/students'
)
// Get list of supervisor's students
.
success
(
function
(
data
)
{
$http
.
get
(
config
.
backend
+
'/sup/'
+
$scope
.
user
.
id
+
'/students'
)
$scope
.
students
=
data
;
.
success
(
function
(
data
)
{
})
$scope
.
students
=
data
;
.
error
(
function
()
{
})
ngToast
.
danger
({
content
:
$translate
.
instant
(
'error_fetching_students'
)
});
.
error
(
function
()
{
});
ngToast
.
danger
({
content
:
$translate
.
instant
(
'error_fetching_students'
)
});
});
}
/**
/**
* Unlink Student
* Unlink Student
...
@@ -242,4 +222,8 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
...
@@ -242,4 +222,8 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
});
});
}
}
});
});
// Main
loadStudents
();
});
});
sails/src/assets/scripts/modules/supervisor/controllers/supervisors.js
View file @
f781c996
...
@@ -69,7 +69,7 @@ dashboardControllers.controller('SupervisorsCtrl', function SupervisorsCtrl($sco
...
@@ -69,7 +69,7 @@ dashboardControllers.controller('SupervisorsCtrl', function SupervisorsCtrl($sco
.
post
(
config
.
backend
+
'/sup/'
+
$scope
.
supToAdd
.
id
+
'/off/'
+
$scope
.
user
.
id
)
.
post
(
config
.
backend
+
'/sup/'
+
$scope
.
supToAdd
.
id
+
'/off/'
+
$scope
.
user
.
id
)
.
success
(
function
(
data
,
status
,
headers
,
config
)
{
.
success
(
function
(
data
,
status
,
headers
,
config
)
{
loadSupervisors
();
loadSupervisors
();
ngToast
.
success
(
$translate
.
instant
(
'supervisor_added'
));
ngToast
.
success
(
$translate
.
instant
(
'supervisor_added
_notified
'
));
})
})
.
error
(
function
(
error
)
{
.
error
(
function
(
error
)
{
var
message
=
typeof
error
==
'string'
?
error
:
error
.
message
;
var
message
=
typeof
error
==
'string'
?
error
:
error
.
message
;
...
...
sails/src/assets/scripts/modules/supervisor/views/instructions.html
View file @
f781c996
<!-- InstructionsCtrl controls here, see app.js -->
<!-- InstructionsCtrl controls here, see app.js -->
<div
class=
"panel panel-default"
>
<div
class=
"panel-heading"
><h3
translate
>
own_instructions
</h3></div>
<div
class=
"panel-body"
>
<div
class=
"row"
>
<div
class=
"panel panel-default"
>
<div
class=
"col-sm-6"
>
<!-- Default panel contents -->
<!-- Select to add new method -->
<div
class=
"panel-heading"
>
<div
class=
"form-group"
>
<div
class=
"row"
>
<!-- Botón añadir método -->
<div
class=
"col-xs-4"
>
<button
ng-click=
"add_method()"
class=
"btn btn-success btn-sm"
popover=
"{{ 'add' | translate }}"
popover-trigger=
"mouseenter"
>
<h3
translate
>
own_instructions
</h3>
<span
class=
"glyphicon glyphicon-plus"
aria-hidden=
"true"
></span>
<span
translate
>
new_method
</span>
</div>
</button>
<div
class=
"col-xs-4 margin-top20"
>
</div>
<div
class=
"form-group"
>
</div>
<!-- Botón añadir método -->
<button
ng-click=
"add_method()"
class=
"btn btn-success btn-sm"
popover=
"{{ 'add' | translate }}"
popover-trigger=
"mouseenter"
>
<div
class=
"col-sm-6 text-right"
ng-if=
"!minimalMode"
>
<span
class=
"glyphicon glyphicon-plus"
aria-hidden=
"true"
></span>
<span
translate
>
new_method
</span>
<button
class=
"btn btn-primary"
ng-click=
"enable_minimal()"
><i
class=
"fa fa-eye-slash"
aria-hidden=
"true"
></i>
Ver menos detalles
</button>
</button>
</div>
<div
class=
"col-sm-6 text-right"
ng-if=
"minimalMode"
>
<button
class=
"btn btn-primary"
ng-click=
"enable_minimal()"
><i
class=
"fa fa-eye"
aria-hidden=
"true"
></i>
Ver todo
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"panel-body"
>
<div
class=
"row"
>
<div
class=
"col-sm-12 text-right"
ng-if=
"!minimalMode"
>
<button
class=
"btn btn-primary"
ng-click=
"enable_minimal()"
><i
class=
"fa fa-eye-slash"
aria-hidden=
"true"
></i>
Ver menos detalles
</button>
</div>
<div
class=
"col-sm-12 text-right"
ng-if=
"minimalMode"
>
<button
class=
"btn btn-primary"
ng-click=
"enable_minimal()"
><i
class=
"fa fa-eye"
aria-hidden=
"true"
></i>
Ver todo
</button>
</div>
</div>
<!-- Method instructions -->
<!-- Method instructions -->
<div
class=
"method"
ng-repeat=
"m in methods"
>
<div
class=
"method"
ng-repeat=
"m in methods"
>
...
...
sails/src/assets/scripts/modules/supervisor/views/students.html
View file @
f781c996
<!-- 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 -->
<div
class=
"panel-heading"
><h3
class=
"color-green"
translate
>
students
</h3>
<div
class=
"panel-heading"
>
<!-- span ng-if="user.isAdmin">({{user.office.currentStudents}}/{{user.office.maxStudents}} - <span translate="licenses_left" translate-values="{number: num_licenses_left}"></span>)</span -->
<div
class=
"row"
>
<div
class=
"panel-body"
>
<div
class=
"col-xs-4"
>
<h3
translate
>
students
</h3>
</div>
<div
class=
"col-xs-4 margin-top20"
>
<!-- Add Student Form -->
<p
class=
"text-left"
ng-hide=
"slide.show"
>
<div
ng-include=
"'modules/supervisor/views/students_add.html'"
hidden=
"true"
id=
"addform"
></div>
<a
ng-click=
"showForm()"
class=
"btn btn-success btn-sm"
role=
"button"
>
<span
class=
"glyphicon glyphicon-plus"
aria-hidden=
"true"
></span>
{{ 'add_student' | translate }}
</a>
</p>
<!-- Add Student button and Search row -->
<p
class=
"text-left"
ng-show=
"slide.show"
>
<div
class=
"row"
>
<a
ng-click=
"hideForm()"
class=
"btn btn-danger btn-sm"
role=
"button"
>
<div
class=
"col-xs-3"
>
<span
class=
"glyphicon glyphicon-remove"
aria-hidden=
"true"
></span>
{{ 'close' | translate }}
<p
class=
"text-left"
ng-hide=
"slide.show"
>
</a>
<a
ng-click=
"showForm()"
class=
"btn btn-success btn-sm"
role=
"button"
>
</p>
<span
class=
"glyphicon glyphicon-plus"
aria-hidden=
"true"
></span>
{{ 'add_student' | translate }}
</a>
</div>
</p>
<div
class=
"col-xs-4 margin-top20"
>
</div>
<div
class=
" input-group"
>
<div
class=
"col-xs-6 input-group"
>
<input
type=
"text"
ng-model=
"search_students"
id=
"search_students"
placeholder=
"{{ 'filter' | translate }}"
class=
"form-control"
aria-describedby=
"basic-addon2"
>
<input
type=
"text"
ng-model=
"search_students"
id=
"search_students"
placeholder=
"{{ 'filter' | translate }}"
class=
"form-control"
aria-describedby=
"basic-addon2"
>
<span
class=
"input-group-addon"
><span
class=
"glyphicon glyphicon-search"
id=
"basic-addon2"
aria-hidden=
"true"
></span></span>
<span
class=
"input-group-addon"
><span
class=
"glyphicon glyphicon-search"
id=
"basic-addon2"
aria-hidden=
"true"
></span></span>
</div>
</div>
<div
class=
"col-xs-3"
>
</div>
</div>
</div>
</div>
</div>
<!-- Fin .panel-body -->
</div>
<!-- Add Student Form -->
<div
ng-include=
"'modules/supervisor/views/students_add.html'"
hidden=
"true"
id=
"addform"
></div>
</div>
<!-- Fin .panel-body -->
<!-- Table -->
<!-- Table -->
<div
ng-show=
"students.length == 0"
>
<div
class=
"table-responsive"
>
{{ no_students_for_user | translate }}
</div>
<table
id=
"table_students"
class=
"table table-hover"
>
<table
id=
"table_students"
class=
"table table-hover"
>
<tr
ng-repeat=
"student in students | filter:search_students | orderBy: ['surname', 'name']"
>
<tr
ng-repeat=
"student in students | filter:search_students | orderBy: ['surname', 'name']"
>
<td>
<td>
...
@@ -110,5 +116,11 @@
...
@@ -110,5 +116,11 @@
</td>
</td>
</tr>
</tr>
</table>
</table>
<div
class=
"alert alert-warning"
ng-if=
"students.length == 0"
>
<strong
translate
>
no_students
</strong>
. {{ 'no_students_desc' | translate }}.
</div>
</div>
</div>
<!-- Fin de row -->
<!-- Fin de row -->
sails/src/assets/scripts/modules/supervisor/views/students_add.html
View file @
f781c996
<div
class=
"row"
>
<div
class=
"col-xs-3"
>
<p
class=
"text-left"
>
<a
ng-click=
"hideForm()"
class=
"btn btn-danger btn-sm"
role=
"button"
>
<span
class=
"glyphicon glyphicon-remove"
aria-hidden=
"true"
></span>
{{ 'close' | translate }}
</a>
</p>
</div>
<div
class=
"col-xs-9"
></div>
</div>
<div
class=
"switch-panel-body height400"
ng-switch=
"slide.state"
>
<div
class=
"switch-panel-body height400"
ng-switch=
"slide.state"
>
...
...
sails/src/assets/scripts/modules/supervisor/views/supervisors_list.html
View file @
f781c996
...
@@ -9,7 +9,11 @@
...
@@ -9,7 +9,11 @@
<div
class=
"col-xs-4 margin-top20"
>
<div
class=
"col-xs-4 margin-top20"
>
<div
class=
" input-group"
>
<div
class=
" input-group"
>
<input
type=
"text"
ng-model=
"inputs.email"
placeholder=
"{{ 'email' | translate }}"
class=
"form-control"
>
<input
type=
"text"
ng-model=
"inputs.email"
placeholder=
"{{ 'email' | translate }}"
class=
"form-control"
>
<span
class=
"input-group-btn"
>
<button
ng-click=
"searchSup()"
class=
"btn btn-success btn-sm"
role=
"button"
>
{{ 'link_supervisor' | translate }}
</button></span>
<span
class=
"input-group-btn"
popover=
"{{ 'link_supervisor_desc' | translate }}"
popover-trigger=
"mouseenter"
>
<button
ng-click=
"searchSup()"
class=
"btn btn-success btn-sm"
role=
"button"
>
{{ 'link_supervisor' | translate }}
</button>
</span>
</div>
</div>
<!-- Alert and success messages for supervisor found -->
<!-- Alert and success messages for supervisor found -->
...
...
sails/src/config/locales/en-gb.json
View file @
f781c996
...
@@ -8,5 +8,6 @@
...
@@ -8,5 +8,6 @@
"therapist_office_request"
:
"{{ name }}, with email {{ email }}, is requesting to be linked as therapist to any of your students."
,
"therapist_office_request"
:
"{{ name }}, with email {{ email }}, is requesting to be linked as therapist to any of your students."
,
"tutor_office_request"
:
"{{ name }}, with email {{ email }}, is requesting to be linked as tutor/father/mother to any of your students."
,
"tutor_office_request"
:
"{{ name }}, with email {{ email }}, is requesting to be linked as tutor/father/mother to any of your students."
,
"welcome_msg1"
:
"Welcome to Pictogram, {{ name }}!"
,
"welcome_msg1"
:
"Welcome to Pictogram, {{ name }}!"
,
"welcome_msg2"
:
"Your account is now active. You can proceed to"
"welcome_msg2"
:
"Your account is now active. You can proceed to"
,
"office_link"
:
"The office/center
\"
{{ name }}
\"
with email
\"
{{ email }}
\"
has added you as part of its team in Pictogram."
}
}
sails/src/config/locales/es-es.json
View file @
f781c996
...
@@ -8,5 +8,6 @@
...
@@ -8,5 +8,6 @@
"therapist_office_request"
:
"El/la terapeuta {{ name }}, con correo electrónico {{ email }}, pide ser asociado a algún estudiante."
,
"therapist_office_request"
:
"El/la terapeuta {{ name }}, con correo electrónico {{ email }}, pide ser asociado a algún estudiante."
,
"tutor_office_request"
:
"El/la tutor/a/padre/madre {{ name }}, con correo electrónico {{ email }}, pide ser asociado a algún estudiante."
,
"tutor_office_request"
:
"El/la tutor/a/padre/madre {{ name }}, con correo electrónico {{ email }}, pide ser asociado a algún estudiante."
,
"welcome_msg1"
:
"¡Bienvenido a Pictogram, {{ name }}!"
,
"welcome_msg1"
:
"¡Bienvenido a Pictogram, {{ name }}!"
,
"welcome_msg2"
:
"Su cuenta está ahora activa, por lo que puede"
"welcome_msg2"
:
"Su cuenta está ahora activa, por lo que puede"
,
"office_link"
:
"El centro/gabinete
\"
{{ name }}
\"
, con correo electrónico
\"
{{ email }}
\"
le ha añadido como parte de su equipo."
}
}
sails/src/config/policies.js
View file @
f781c996
...
@@ -138,7 +138,8 @@ module.exports.policies = {
...
@@ -138,7 +138,8 @@ module.exports.policies = {
list
:
[
'tokenAuth'
,
'isAdmin'
],
list
:
[
'tokenAuth'
,
'isAdmin'
],
students
:
[
'tokenAuth'
],
students
:
[
'tokenAuth'
],
pictos
:
[
'tokenAuth'
],
pictos
:
[
'tokenAuth'
],
getByEmail
:
[
'tokenAuth'
],
getByEmail
:
[
'tokenAuth'
,
'isOffice'
],
getFromOfficeByEmail
:
[
'tokenAuth'
,
'isOffice'
],
update
:
[
'tokenAuth'
],
update
:
[
'tokenAuth'
],
create
:
true
,
create
:
true
,
login
:
true
,
login
:
true
,
...
...
sails/src/config/routes.js
View file @
f781c996
...
@@ -82,8 +82,6 @@ module.exports.routes = {
...
@@ -82,8 +82,6 @@ module.exports.routes = {
'GET /stu/:id_stu'
:
'StudentController.getInfo'
,
'GET /stu/:id_stu'
:
'StudentController.getInfo'
,
'GET /stu/:id_stu/supervisors'
:
'StudentController.supervisors'
,
'GET /stu/:id_stu/supervisors'
:
'StudentController.supervisors'
,
'GET /stu/:id_stu/therapists'
:
'StudentController.therapists'
,
'GET /stu/:id_stu/tutors'
:
'StudentController.tutors'
,
'POST /stu/license/sup/:id_sup'
:
"StudentController.link_supervisor"
,
'POST /stu/license/sup/:id_sup'
:
"StudentController.link_supervisor"
,
'POST /stu/:id_stu/sup/:id_sup'
:
'StudentController.link_supervisor'
,
'POST /stu/:id_stu/sup/:id_sup'
:
'StudentController.link_supervisor'
,
'GET /stu/:id_stu/pictos'
:
'StudentController.pictos'
,
'GET /stu/:id_stu/pictos'
:
'StudentController.pictos'
,
...
@@ -127,6 +125,7 @@ module.exports.routes = {
...
@@ -127,6 +125,7 @@ module.exports.routes = {
'GET /sup/:id/pictos'
:
'SupervisorController.pictos'
,
'GET /sup/:id/pictos'
:
'SupervisorController.pictos'
,
'GET /sup/email/:email'
:
'SupervisorController.getByEmail'
,
'GET /sup/email/:email'
:
'SupervisorController.getByEmail'
,
'GET /sup/off/email/:email'
:
'SupervisorController.getFromOfficeByEmail'
,
'GET /sup/changepass/:email'
:
'SupervisorController.request_change_password'
,
'GET /sup/changepass/:email'
:
'SupervisorController.request_change_password'
,
'GET /sup/arasaac_license/:id'
:
'SupervisorController.accept_arasaac'
,
'GET /sup/arasaac_license/:id'
:
'SupervisorController.accept_arasaac'
,
'PUT /sup/changepass'
:
'SupervisorController.change_password'
,
'PUT /sup/changepass'
:
'SupervisorController.change_password'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment