Commit 2e789223 by Arturo Montejo Ráez

fixed merge conflicts

parents 03bef2e9 cb78814c
Showing with 263 additions and 181 deletions
...@@ -10,7 +10,7 @@ android { ...@@ -10,7 +10,7 @@ android {
versionCode 1 versionCode 1
versionName "1.3" versionName "1.3"
resValue "string", "db_name", "PCB.db" resValue "string", "db_name", "PCB.db"
resValue "integer", "db_version", "8" resValue "integer", "db_version", "10"
//resValue "string", "app_version", "1.1" //resValue "string", "app_version", "1.1"
resValue "string", "core_vocabulary", "core_vocabulary" resValue "string", "core_vocabulary", "core_vocabulary"
resValue "string", "apk", "to_be_set_in_subproject" resValue "string", "apk", "to_be_set_in_subproject"
......
...@@ -5,7 +5,6 @@ import android.util.Log; ...@@ -5,7 +5,6 @@ import android.util.Log;
import com.yottacode.net.RestapiWrapper; import com.yottacode.net.RestapiWrapper;
import com.yottacode.pictogram.R; import com.yottacode.pictogram.R;
import com.yottacode.pictogram.action.PictoAction;
import com.yottacode.pictogram.action.VocabularyAction; import com.yottacode.pictogram.action.VocabularyAction;
import com.yottacode.pictogram.dao.Picto; import com.yottacode.pictogram.dao.Picto;
import com.yottacode.pictogram.net.ImgDownloader; import com.yottacode.pictogram.net.ImgDownloader;
...@@ -69,6 +68,7 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -69,6 +68,7 @@ public class Vocabulary implements Iterable<Picto> {
VocabularyTalk.iVocabularyListener vocabulary_listeners[] = {new VocabularyTalk.iVocabularyListener() { VocabularyTalk.iVocabularyListener vocabulary_listeners[] = {new VocabularyTalk.iVocabularyListener() {
@Override @Override
public void change(action action, int picto_cat, int picto_id, JSONObject args) { public void change(action action, int picto_cat, int picto_id, JSONObject args) {
switch (action) { switch (action) {
case delete: { case delete: {
removePicto(picto_cat, picto_id); removePicto(picto_cat, picto_id);
...@@ -189,7 +189,7 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -189,7 +189,7 @@ public class Vocabulary implements Iterable<Picto> {
@Override @Override
public void result(JSONObject result) { public void result(JSONObject result) {
if (result != null) { if (result != null && PCBcontext.is_user_logged()) {
JSONObject picto, attributes; JSONObject picto, attributes;
JSONObject stupicto = null; JSONObject stupicto = null;
try { try {
...@@ -207,12 +207,11 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -207,12 +207,11 @@ public class Vocabulary implements Iterable<Picto> {
stupicto.getInt("id"), stupicto.getInt("id"),
attributes); attributes);
} }
synchronizeImgs(pictos); synchronizeImgs(pictos);
if (PCBcontext.is_user_logged()) { PCBcontext.getPcbdb().setStudentVocabulary(Vocabulary.this);
PCBcontext.getPcbdb().setStudentVocabulary(Vocabulary.this); PCBcontext.getPcbdb().setActiveSceneForStudent(result); //Aqui inserto en scene los datos que llegan de la activa
PCBcontext.getPcbdb().setActiveSceneForStudent(result); //Aqui inserto en scene los datos que llegan de la activa
}else
Log.i(this.getClass().getName(), "Downloaded images ended when the user comes to logout");
Log.i(this.getClass().getName(), " Pictos downloaded: " + result.getJSONArray("pictos").length()); Log.i(this.getClass().getName(), " Pictos downloaded: " + result.getJSONArray("pictos").length());
} catch (JSONException e) { } catch (JSONException e) {
StackTraceElement traces[] = e.getStackTrace(); StackTraceElement traces[] = e.getStackTrace();
...@@ -222,6 +221,7 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -222,6 +221,7 @@ public class Vocabulary implements Iterable<Picto> {
this.error(new RestapiWrapper.HTTPException("JSON Error:" + e.getMessage(), -1)); this.error(new RestapiWrapper.HTTPException("JSON Error:" + e.getMessage(), -1));
} }
} }
else Log.e(this.getClass().getName(), "Downloaded images ended when the user comes to logout");
} }
@Override @Override
...@@ -368,7 +368,10 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -368,7 +368,10 @@ public class Vocabulary implements Iterable<Picto> {
int index=find_picto_index(pic_cat, pic_id); int index=find_picto_index(pic_cat, pic_id);
if (index>=0) { //puede ocurrir que se intente modificar un pictograma que fue borrado if (index>=0) { //puede ocurrir que se intente modificar un pictograma que fue borrado
Picto picto = this.pictos.get(pic_cat).get(index); Picto picto = this.pictos.get(pic_cat).get(index);
String old_legend=picto.get_legend();
picto.set_json_attr(attrs); picto.set_json_attr(attrs);
if (!old_legend.equals(picto.get_legend())) //puede ocurrir que se cambie la leyenda de TODOS los pictos
this.synchronize();
PCBcontext.getPcbdb().modifyPicto(pic_id, attrs.toString()); PCBcontext.getPcbdb().modifyPicto(pic_id, attrs.toString());
} }
else else
......
package com.yottacode.pictogram.net; package com.yottacode.pictogram.net;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.util.Log; import android.util.Log;
import com.yottacode.net.RestapiWrapper; import com.yottacode.net.RestapiWrapper;
...@@ -76,12 +75,12 @@ public class NetService implements Runnable, RestapiWrapper.iSilentLogin { ...@@ -76,12 +75,12 @@ public class NetService implements Runnable, RestapiWrapper.iSilentLogin {
} }
@Override @Override
public void result(JSONObject result) { public void result(JSONObject result) { PCBcontext.getPcbdb().user_online(true);
} }
@Override @Override
public void error(RestapiWrapper.HTTPException e) { public void error(RestapiWrapper.HTTPException e) {
Log.e(this.getClass().getSimpleName(), "Error un when server login:" + e.getMessage()+"( error "+e.getCode()+")"); Log.e(this.getClass().getSimpleName(), "Error when server login:" + e.getMessage()+"( error "+e.getCode()+")");
if (e instanceof LoginException) if (e instanceof LoginException)
for (iNetServiceStatus listener: listeners) for (iNetServiceStatus listener: listeners)
if (listener instanceof iNetServiceDevice) ((iNetServiceDevice)listener).restart_app(false); if (listener instanceof iNetServiceDevice) ((iNetServiceDevice)listener).restart_app(false);
...@@ -100,7 +99,7 @@ public class NetService implements Runnable, RestapiWrapper.iSilentLogin { ...@@ -100,7 +99,7 @@ public class NetService implements Runnable, RestapiWrapper.iSilentLogin {
@Override @Override
public void result(JSONObject result) { public void result(JSONObject result) {
PCBcontext.getPcbdb().user_online(true);
} }
@Override @Override
...@@ -217,7 +216,7 @@ public class NetService implements Runnable, RestapiWrapper.iSilentLogin { ...@@ -217,7 +216,7 @@ public class NetService implements Runnable, RestapiWrapper.iSilentLogin {
return restfullSynchroTimming; return restfullSynchroTimming;
} }
private void synchronizeStudentAttributes() { public void synchronizeStudentAttributes() {
int id=PCBcontext.getPcbdb().getCurrentUser().get_id_stu(); int id=PCBcontext.getPcbdb().getCurrentUser().get_id_stu();
PCBcontext.getRestapiWrapper().ask("stu/" + id, new RestapiWrapper.iRestapiListener() { PCBcontext.getRestapiWrapper().ask("stu/" + id, new RestapiWrapper.iRestapiListener() {
@Override @Override
......
...@@ -41,7 +41,9 @@ public class StudentTalk implements Emitter.Listener { ...@@ -41,7 +41,9 @@ public class StudentTalk implements Emitter.Listener {
String pic=msg.getString("pic"); String pic=msg.getString("pic");
String lang=msg.getString("lang"); String lang=msg.getString("lang");
String attributes=msg.getString("attributes"); String attributes=msg.getString("attributes");
JSONObject license=msg.getJSONObject("license"); //JSONObject license= msg.getJSONObject("license");
Log.e("STUDENT","change...remove license in hard when lincense is not null");
JSONObject license=new JSONObject().put("isValid",true);
User user=PCBcontext.getPcbdb().getCurrentUser(); User user=PCBcontext.getPcbdb().getCurrentUser();
User updatedUser=new User(id, username, user.get_pwd_stu(), name, surname, id_active_scene, pic, gender, lang, attributes, User updatedUser=new User(id, username, user.get_pwd_stu(), name, surname, id_active_scene, pic, gender, lang, attributes,
user.get_id_sup(), user.get_email_sup(), user.get_pwd_sup(), user.get_name_sup(), user.get_surname_sup(), user.get_url_img_sup(), user.get_gender_sup(), user.get_id_sup(), user.get_email_sup(), user.get_pwd_sup(), user.get_name_sup(), user.get_surname_sup(), user.get_url_img_sup(), user.get_gender_sup(),
......
...@@ -23,6 +23,7 @@ import org.json.JSONException; ...@@ -23,6 +23,7 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
public final class PCBcontext { public final class PCBcontext {
private static final String LOG_TAG =PCBcontext.class.getName();
private static Context context; private static Context context;
private static PCBDBHelper pcbdb; private static PCBDBHelper pcbdb;
private static Device device=null; private static Device device=null;
...@@ -107,8 +108,10 @@ public final class PCBcontext { ...@@ -107,8 +108,10 @@ public final class PCBcontext {
PCBcontext.getDevice().insertUser(updatedStudent); PCBcontext.getDevice().insertUser(updatedStudent);
if (updatedStudent.is_picto_size_big()!=getPcbdb().getCurrentUser().is_picto_size_big() || PCBcontext.getVocabulary().has_categories() != vocabulary.has_categories() if (updatedStudent.is_picto_size_big()!=getPcbdb().getCurrentUser().is_picto_size_big() || PCBcontext.getVocabulary().has_categories() != vocabulary.has_categories()
|| updatedStudent.get_active_scene() != PCBcontext.getPcbdb().getCurrentUser().get_active_scene()) || updatedStudent.get_active_scene() != PCBcontext.getPcbdb().getCurrentUser().get_active_scene()) {
PCBcontext.getNetService().restart_app(false); Log.e(LOG_TAG, "Major config modification. Restarting is mandatory");
PCBcontext.getNetService().restart_app(false);
}
else { else {
PCBcontext.getPcbdb().setCurrentUser(updatedStudent); PCBcontext.getPcbdb().setCurrentUser(updatedStudent);
PCBcontext.getNetService().getNetServiceDevice().updateUserConfig(updatedStudent, valid_license); PCBcontext.getNetService().getNetServiceDevice().updateUserConfig(updatedStudent, valid_license);
......
...@@ -49,7 +49,7 @@ pwd TEXT(40) NOT NULL, ...@@ -49,7 +49,7 @@ pwd TEXT(40) NOT NULL,
name TEXT(40) NOT NULL, name TEXT(40) NOT NULL,
surname TEXT(60) NOT NULL, surname TEXT(60) NOT NULL,
url_img VARCHAR(250) NOT NULL, url_img VARCHAR(250) NOT NULL,
gender TEXT(1) NOT NULL CHECK (gender IN ('M','F')), gender TEXT(1) NULL CHECK (gender IN (NULL, 'M','F')),
lang TEXT(5) NOT NULL CHECK (lang in ('en-gb','en-us','es-es')), lang TEXT(5) NOT NULL CHECK (lang in ('en-gb','en-us','es-es')),
tts_engine TEXT(100) NULL, tts_engine TEXT(100) NULL,
office TEXT(140) NULL office TEXT(140) NULL
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<string name="loginErrorTxt">Login</string> <string name="loginErrorTxt">Login</string>
<string name="loginErrorMsg">Invalid user or password. Please, try it again.</string> <string name="loginErrorMsg">Invalid user or password. Please, try it again.</string>
<string name="loginNoLicenseMsg">Not valid user license. Please, contact with Yotta.</string> <string name="loginNoLicenseMsg">Not valid user license. Please, contact with Yotta.</string>
<string name="loginExpiredLicenseMsg">User license was expired on</string> <string name="loginExpiredLicenseMsg">User license was expired. Please contact with Yotta.</string>
<string name="userInetErrorMsg">Unknown new user name because Internet conection is not available</string> <string name="userInetErrorMsg">Unknown new user name because Internet conection is not available</string>
<string name="userLoadingTxt">Loading</string> <string name="userLoadingTxt">Loading</string>
<string name="userLoadingMsg">Loading students. Please wait.</string> <string name="userLoadingMsg">Loading students. Please wait.</string>
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
<string name="fa_flask">&#xf0c3;</string> <string name="fa_flask">&#xf0c3;</string>
<string name="fa_exclamation_triangle">&#xf071;</string> <string name="fa_exclamation_triangle">&#xf071;</string>
<string name="fa_user_plus">&#xf234;</string> <string name="fa_user_plus">&#xf234;</string>
<string name="fa_question_circle">&#xf059;</string>
<string name="google_play_student_apk">https://play.google.com/store/apps/details?id=com.yottacode.yotta_tablet</string> <string name="google_play_student_apk">https://play.google.com/store/apps/details?id=com.yottacode.yotta_tablet</string>
<string name="google_play_supervisor_apk">https://play.google.com/store/apps/details?id=com.yottacode.supervisor_tablet</string> <string name="google_play_supervisor_apk">https://play.google.com/store/apps/details?id=com.yottacode.supervisor_tablet</string>
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<string name="loginErrorTxt">Login</string> <string name="loginErrorTxt">Login</string>
<string name="loginErrorMsg">El usuario no existe o la contraseña indicada no es correcta. Inténtelo de nuevo.</string> <string name="loginErrorMsg">El usuario no existe o la contraseña indicada no es correcta. Inténtelo de nuevo.</string>
<string name="loginNoLicenseMsg">Licencia incorrecta o caducada. Contacte con Yotta para adquirir una.</string> <string name="loginNoLicenseMsg">Licencia incorrecta o caducada. Contacte con Yotta para adquirir una.</string>
<string name="loginExpiredLicenseMsg">La licencia del usuario expiró con fecha</string> <string name="loginExpiredLicenseMsg">La licencia del usuario expiró. Contacte con Yotta para ampliar la licencia actual</string>
<string name="imguserLoadingMsg">Cargando imágenes de los alumnos. Por favor espere.</string> <string name="imguserLoadingMsg">Cargando imágenes de los alumnos. Por favor espere.</string>
<string name="imguserLoadingErrMsg">Imagen con formato no válido.</string> <string name="imguserLoadingErrMsg">Imagen con formato no válido.</string>
...@@ -78,6 +78,7 @@ ...@@ -78,6 +78,7 @@
<string name="fa_certificate">&#xf0a3;</string> <string name="fa_certificate">&#xf0a3;</string>
<string name="fa_flask">&#xf0c3;</string> <string name="fa_flask">&#xf0c3;</string>
<string name="fa_exclamation_triangle">&#xf071;</string> <string name="fa_exclamation_triangle">&#xf071;</string>
<string name="fa_question_circle">&#xf059;</string>
<string name="fa_user_plus">&#xf234;</string> <string name="fa_user_plus">&#xf234;</string>
<string name="google_play_student_apk">https://play.google.com/store/apps/details?id=com.yottacode.yotta_tablet</string> <string name="google_play_student_apk">https://play.google.com/store/apps/details?id=com.yottacode.yotta_tablet</string>
<string name="google_play_supervisor_apk">https://play.google.com/store/apps/details?id=com.yottacode.supervisor_tablet</string> <string name="google_play_supervisor_apk">https://play.google.com/store/apps/details?id=com.yottacode.supervisor_tablet</string>
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
<string name="loginErrorTxt">Login</string> <string name="loginErrorTxt">Login</string>
<string name="loginErrorMsg">El usuario no existe o la contraseña indicada no es correcta. Inténtelo de nuevo.</string> <string name="loginErrorMsg">El usuario no existe o la contraseña indicada no es correcta. Inténtelo de nuevo.</string>
<string name="loginNoLicenseMsg">El usuario no tiene una licencia válida. Contacte con Yotta para adquirir una.</string> <string name="loginNoLicenseMsg">El usuario no tiene una licencia válida. Contacte con Yotta para adquirir una.</string>
<string name="loginExpiredLicenseMsg">La licencia del usuario expiró con fecha</string> <string name="loginExpiredLicenseMsg">La licencia del usuario expiró. Contacte con Yotta para ampliar la licencia actual</string>
<string name="userInetErrorMsg">Este usuario requiere conexión a internet para ser validado</string> <string name="userInetErrorMsg">Este usuario requiere conexión a internet para ser validado</string>
<string name="userLoadingTxt">Cargando</string> <string name="userLoadingTxt">Cargando</string>
<string name="userLoadingMsg">Cargando alumnos. Por favor espere.</string> <string name="userLoadingMsg">Cargando alumnos. Por favor espere.</string>
...@@ -84,6 +84,7 @@ ...@@ -84,6 +84,7 @@
<string name="fa_flask">&#xf0c3;</string> <string name="fa_flask">&#xf0c3;</string>
<string name="fa_exclamation_triangle">&#xf071;</string> <string name="fa_exclamation_triangle">&#xf071;</string>
<string name="fa_user_plus">&#xf234;</string> <string name="fa_user_plus">&#xf234;</string>
<string name="fa_question_circle">&#xf059;</string>
<string name="google_play_student_apk">https://play.google.com/store/apps/details?id=com.yottacode.yotta_tablet</string> <string name="google_play_student_apk">https://play.google.com/store/apps/details?id=com.yottacode.yotta_tablet</string>
<string name="google_play_supervisor_apk">https://play.google.com/store/apps/details?id=com.yottacode.supervisor_tablet</string> <string name="google_play_supervisor_apk">https://play.google.com/store/apps/details?id=com.yottacode.supervisor_tablet</string>
</resources> </resources>
...@@ -5,10 +5,8 @@ import android.app.Activity; ...@@ -5,10 +5,8 @@ import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.ClipData; import android.content.ClipData;
import android.content.ClipDescription; import android.content.ClipDescription;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.PixelFormat;
import android.media.Ringtone; import android.media.Ringtone;
import android.media.RingtoneManager; import android.media.RingtoneManager;
import android.net.Uri; import android.net.Uri;
...@@ -18,14 +16,12 @@ import android.speech.tts.UtteranceProgressListener; ...@@ -18,14 +16,12 @@ import android.speech.tts.UtteranceProgressListener;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.view.DragEvent; import android.view.DragEvent;
import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.TranslateAnimation; import android.view.animation.TranslateAnimation;
...@@ -51,7 +47,6 @@ import com.yottacode.pictogram.tabletlibrary.net.NetServiceTablet; ...@@ -51,7 +47,6 @@ import com.yottacode.pictogram.tabletlibrary.net.NetServiceTablet;
import com.yottacode.pictogram.tools.Img; import com.yottacode.pictogram.tools.Img;
import com.yottacode.pictogram.tools.PCBcontext; import com.yottacode.pictogram.tools.PCBcontext;
import com.yottacode.pictogram.tts.TTSHelper; import com.yottacode.pictogram.tts.TTSHelper;
import com.yottacode.tools.GUITools;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
......
...@@ -2,12 +2,8 @@ package com.yottacode.pictogram.tabletlibrary.gui.login; ...@@ -2,12 +2,8 @@ package com.yottacode.pictogram.tabletlibrary.gui.login;
import android.app.Activity; import android.app.Activity;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.provider.ContactsContract;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
...@@ -22,9 +18,8 @@ import java.util.Vector; ...@@ -22,9 +18,8 @@ import java.util.Vector;
import static com.yottacode.pictogram.R.string.fa_certificate; import static com.yottacode.pictogram.R.string.fa_certificate;
import static com.yottacode.pictogram.R.string.fa_flask; import static com.yottacode.pictogram.R.string.fa_flask;
import static com.yottacode.pictogram.R.string.fa_exclamation_triangle;
import static com.yottacode.pictogram.R.string.fa_user_plus; import static com.yottacode.pictogram.R.string.fa_user_plus;
import static com.yottacode.pictogram.R.string.fa_question_circle;
/** /**
* Creates a View for each student on the list with a photo and his/her name. * Creates a View for each student on the list with a photo and his/her name.
* It uses list_single.xml for the layout creation. * It uses list_single.xml for the layout creation.
...@@ -73,8 +68,10 @@ public class CustomList extends ArrayAdapter<String>{ ...@@ -73,8 +68,10 @@ public class CustomList extends ArrayAdapter<String>{
// License, except add student view // License, except add student view
TextView licenseView = (TextView) rowView.findViewById(R.id.loginStudentLicense); TextView licenseView = (TextView) rowView.findViewById(R.id.loginStudentLicense);
licenseView.setTypeface(fontAwesome); licenseView.setTypeface(fontAwesome);
if (!PCBcontext.getNetService().online()) {
if(licenses[position].equals("pro")) { licenseView.setText(fa_question_circle);
licenseView.setTextColor(getContext().getResources().getColor(R.color.text_danger));
}else if(licenses[position].equals("pro")) {
licenseView.setText(fa_certificate); licenseView.setText(fa_certificate);
licenseView.setTextColor(getContext().getResources().getColor(R.color.text_primary)); licenseView.setTextColor(getContext().getResources().getColor(R.color.text_primary));
}else if (licenses[position].equals("trial")) { }else if (licenses[position].equals("trial")) {
......
...@@ -8,7 +8,6 @@ import android.content.Intent; ...@@ -8,7 +8,6 @@ import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.text.Editable;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
...@@ -116,7 +115,8 @@ public class StudentFragmentGrid extends Fragment { ...@@ -116,7 +115,8 @@ public class StudentFragmentGrid extends Fragment {
return; return;
} }
new_user(i); new_user(i, licenseStudents[i].equals("pro") || licenseStudents[i].equals("trial") );
download_supervisors(PCBcontext.getPcbdb().getCurrentUser().get_id_stu()); download_supervisors(PCBcontext.getPcbdb().getCurrentUser().get_id_stu());
} }
} }
...@@ -179,8 +179,9 @@ public class StudentFragmentGrid extends Fragment { ...@@ -179,8 +179,9 @@ public class StudentFragmentGrid extends Fragment {
/** /**
* Change user data, load vocabulary and goes to VOCA Activity * Change user data, load vocabulary and goes to VOCA Activity
* @param i Position on students downloaded collection * @param i Position on students downloaded collection
* @param license_valid
*/ */
private void new_user(int i) { private void new_user(int i, final boolean license_valid) {
JSONObject st = this.downloaded_students.get(i); JSONObject st = this.downloaded_students.get(i);
Intent intent = getActivity().getIntent(); Intent intent = getActivity().getIntent();
...@@ -220,6 +221,7 @@ public class StudentFragmentGrid extends Fragment { ...@@ -220,6 +221,7 @@ public class StudentFragmentGrid extends Fragment {
public void loadComplete() { public void loadComplete() {
if (progressDialog != null && progressDialog.isShowing()) if (progressDialog != null && progressDialog.isShowing())
progressDialog.dismiss(); progressDialog.dismiss();
PCBcontext.getPcbdb().user_valid(license_valid);
Intent pictogramActivity = new Intent(getActivity(), VOCA.class); Intent pictogramActivity = new Intent(getActivity(), VOCA.class);
startActivity(pictogramActivity); startActivity(pictogramActivity);
} }
......
...@@ -59,7 +59,13 @@ public class ListInstructionsFragment extends Fragment{ ...@@ -59,7 +59,13 @@ public class ListInstructionsFragment extends Fragment{
@Override @Override
public void onStart() { public void onStart() {
super.onStart(); super.onStart();
checkStudent();
initMethods(getView());
initInstructions(getView());
setMethods();
methodPosition=-1;
instructionPosition=-1;
} }
public void initAdapters() { public void initAdapters() {
...@@ -104,16 +110,12 @@ public class ListInstructionsFragment extends Fragment{ ...@@ -104,16 +110,12 @@ public class ListInstructionsFragment extends Fragment{
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_instructions_session, container, false); View view = inflater.inflate(R.layout.fragment_instructions_session, container, false);
progressDialog = ProgressDialog.show(getActivity(), getString(R.string.session_instruction), getString(R.string.session_loading)); progressDialog = ProgressDialog.show(getActivity(), getString(R.string.session_instruction), getString(R.string.session_loading));
checkStudent();
initMethods(view); return view;
initInstructions(view);
setMethods();
methodPosition=-1;
instructionPosition=-1;
return view;
} }
void close() { void close() {
ListInstructionsFragment.this.getActivity().finish(); ListInstructionsFragment.this.getActivity().finish();
startActivity(new Intent(getActivity(), VOCA.class)); startActivity(new Intent(getActivity(), VOCA.class));
......
...@@ -87,7 +87,7 @@ public class NetServiceTablet implements NetService.iNetServiceDevice { ...@@ -87,7 +87,7 @@ public class NetServiceTablet implements NetService.iNetServiceDevice {
public void restart_app(boolean resetPrevUser) { public void restart_app(boolean resetPrevUser) {
Log.e(LOG_TAG,"App restarting, reset last login:"+resetPrevUser); Log.i(LOG_TAG,"App restarting, reset last login:"+resetPrevUser);
Context context=PCBcontext.getActivityContext(); Context context=PCBcontext.getActivityContext();
......
...@@ -177,7 +177,7 @@ public class SessionWrapper { ...@@ -177,7 +177,7 @@ public class SessionWrapper {
public static void getMethods(final iMethodWrapper listener) { public static void getMethods(final iMethodWrapper listener) {
int id=PCBcontext.getPcbdb().getCurrentUser().get_id_stu(); int id=PCBcontext.getPcbdb().getCurrentUser().get_id_stu();
Log.i(LOG_TAG,"License valid:"+ PCBcontext.getPcbdb().isUser_valid()+" User:"+id+","+PCBcontext.getPcbdb().getCurrentUser().get_name_stu());
PCBcontext.getRestapiWrapper().ask("stu/" + id+"/methods",null,"get",true, new RestapiWrapper.iRestapiListener() { PCBcontext.getRestapiWrapper().ask("stu/" + id+"/methods",null,"get",true, new RestapiWrapper.iRestapiListener() {
@Override @Override
public void preExecute() { public void preExecute() {
...@@ -194,6 +194,7 @@ public class SessionWrapper { ...@@ -194,6 +194,7 @@ public class SessionWrapper {
try { try {
listener.methods(new JSONArray(1).put(result)); listener.methods(new JSONArray(1).put(result));
} catch (JSONException e) { } catch (JSONException e) {
listener.methods(new JSONArray());
listener.error(e.getMessage()); listener.error(e.getMessage());
} }
} }
......
...@@ -6,6 +6,11 @@ ...@@ -6,6 +6,11 @@
state: present state: present
when: ansible_distribution == 'CentOS' or ansible_distribution == 'Amazon' when: ansible_distribution == 'CentOS' or ansible_distribution == 'Amazon'
- name: Install Postfix (for sending emails)
package:
name: postfix
state: present
- name: Install NPM dependencies - name: Install NPM dependencies
npm: npm:
path: "{{ server_path }}/{{ server_relative_path }}" path: "{{ server_path }}/{{ server_relative_path }}"
......
/* global Student, PictoCore, VStuLastInstruction, StuPicto, StuSup, sailsTokenAuth, sails, /* global Student, PictoCore, VStuLastInstruction, StuPicto, StuSup, sailsTokenAuth, sails,
Picto */ Picto */
const generatePassword = require('password-generator');
/** /**
/* StudentController /* StudentController
* *
...@@ -182,7 +184,6 @@ module.exports = { ...@@ -182,7 +184,6 @@ module.exports = {
resolve(params.license_number); resolve(params.license_number);
else { else {
License.newTrial(params.id_sup, function(err, license) { License.newTrial(params.id_sup, function(err, license) {
console.log(license.number);
if (err) if (err)
reject(err); reject(err);
else else
...@@ -193,45 +194,88 @@ module.exports = { ...@@ -193,45 +194,88 @@ module.exports = {
.then((license_number) => { .then((license_number) => {
// Check license // Check license
License.isActivable(license_number, function(err) { return new Promise(function(resolve, reject) {
if (err) { License.isActivable(license_number, function(err) {
return res.badRequest(err.message); if (err)
} reject(err)
else
resolve(license_number);
});
});
// Create student })
Student.create(params) .then((license_number) => {
.then(function(created) { return new Promise(function(resolve, reject) {
sails.log.debug('Student ' + created.id + ' created: ' + JSON.stringify(created)); Student.genUsername(params.name, params.surname, function(username) {
resolve({username: username, license_number: license_number});
});
});
})
.then((info) => {
// Create student
var stuData = {
name: params.name,
surname: params.surname,
password: generatePassword(),
username: info.username,
lang: params.lang
};
Student.create(stuData)
.then(function(created) {
sails.log.debug('Student ' + created.id + ' created: ' + JSON.stringify(created));
// Activate license
License.activate(info.license_number, created.id, function(err, license) {
if (err) {
Student.destroy({id: created.id});
return res.badRequest(err);
}
// Activate license created = created.toJSON();
License.activate(license_number, created.id, function(err, license) { created.license = license.toObject();
if (err) {
// Link to supervisor
StuSup.create({student: created.id, supervisor: params.id_sup})
.then((stu_sup) => {
if (!stu_sup) {
Student.destroy({id: created.id}); Student.destroy({id: created.id});
return res.badRequest(err); return res.serverError("Unable to link to supervisor");
} }
created = created.toJSON(); //
created.license = license.toObject(); // Send sockets messages
//
// Link to supervisor const socketToOmit = (req.isSocket) ? req.socket : undefined;
StuSup.create({student: created.id, supervisor: params.id_sup}) const linkSupervisorToStudentEvent = sails.hooks.events.linkSupervisorToStudent(
.then((stu_sup) => { stu_sup.supervisor,
if (!stu_sup) { stu_sup.student
Student.destroy({id: created.id}); );
return res.serverError("Unable to link to supervisor"); sails.hooks.events.broadcastEvent(
} sails.hooks.rooms.supervisor(stu_sup.supervisor),
return res.ok(created); linkSupervisorToStudentEvent,
}) socketToOmit
.catch((err) => { );
Student.destroy({id: created.id}); sails.hooks.events.broadcastEvent(
throw err sails.hooks.rooms.student(stu_sup.student),
}); linkSupervisorToStudentEvent,
socketToOmit
);
// return OK
return res.ok(created);
})
.catch((err) => {
Student.destroy({id: created.id});
throw err
}); });
})
.catch(function(err) {
sails.log.debug(err.message);
return res.serverError(err.message);
}); });
})
.catch(function(err) {
sails.log.debug(err.message);
return res.serverError(err.message);
}); });
}) })
.catch((err) => {res.serverError(err)}); .catch((err) => {res.serverError(err)});
...@@ -874,9 +918,11 @@ module.exports = { ...@@ -874,9 +918,11 @@ module.exports = {
.then(function(scene){ .then(function(scene){
if(!scene) if(!scene)
throw new Error("Scene not found"); throw new Error("Scene not found");
console.log("scene ID: " + scene.id)
Scene.pictos(scene.id, function(err, pictos){ Scene.pictos(scene.id, function(err, pictos){
if (err) if (err)
return res.serverError("Error obtaining pictos: "+ err); return res.serverError("Error obtaining pictos: "+ err);
scene = scene.toObject();
scene.active = true; scene.active = true;
scene.pictos=pictos; scene.pictos=pictos;
return res.ok(scene); return res.ok(scene);
...@@ -894,6 +940,7 @@ module.exports = { ...@@ -894,6 +940,7 @@ module.exports = {
updateActiveScene: function(req,res){ updateActiveScene: function(req,res){
var params = req.allParams(); var params = req.allParams();
Student.findOne({id:params.id_stu}) Student.findOne({id:params.id_stu})
.populate('license')
.then(student => { .then(student => {
student.id_active_scene=params.id_scene; student.id_active_scene=params.id_scene;
delete student.password; delete student.password;
......
...@@ -4,6 +4,7 @@ const fs = require('fs'); ...@@ -4,6 +4,7 @@ const fs = require('fs');
const path = require('path'); const path = require('path');
const lodash = require('lodash'); const lodash = require('lodash');
const bcrypt = require('bcrypt-nodejs'); const bcrypt = require('bcrypt-nodejs');
const generatePassword = require('password-generator');
/** /**
* SupervisorController * SupervisorController
...@@ -272,7 +273,7 @@ module.exports = { ...@@ -272,7 +273,7 @@ module.exports = {
var params = req.params.all(); var params = req.params.all();
// Send email confirmation -------------------------------- // Send email confirmation --------------------------------
function sendConfirmationMail(supervisor, cb) { function sendConfirmationMail(supervisor, password, cb) {
var token = sailsTokenAuth.issueToken({ var token = sailsTokenAuth.issueToken({
id_sup: supervisor.id, id_sup: supervisor.id,
...@@ -282,7 +283,11 @@ module.exports = { ...@@ -282,7 +283,11 @@ module.exports = {
var message = sails.__({ var message = sails.__({
phrase: 'signin_mail', phrase: 'signin_mail',
locale: params.lang || 'es-es' locale: params.lang || 'es-es'
}) + 'https://' + req.headers.host + '/sup/activate/' + token; // expires in 1 week },
{
url: 'https://' + req.headers.host + '/sup/activate/' + token,
password: password
});
var subject = sails.__({ var subject = sails.__({
phrase: 'notification_from_pictogram', phrase: 'notification_from_pictogram',
...@@ -303,13 +308,17 @@ module.exports = { ...@@ -303,13 +308,17 @@ module.exports = {
sails.log.debug("Creating supervisor with params " + JSON.stringify(params)); sails.log.debug("Creating supervisor with params " + JSON.stringify(params));
if (!params.password || !params.email ) if (!params.name || !params.email || params.role != 'office' && !params.surname)
return res.badRequest("Invalid params"); return res.badRequest("Invalid params");
// randomly generated memorable password
var password = generatePassword();
var supData = { var supData = {
role: params.role, role: params.role,
name: typeof params.name == 'undefined' ? '' : params.name, name: params.name,
password: params.password, surname: params.surname,
password: password,
email: params.email, email: params.email,
pic: sails.config.pictogram.paths.defaultAvatarFileName, pic: sails.config.pictogram.paths.defaultAvatarFileName,
lang: params.lang || 'es-es', lang: params.lang || 'es-es',
...@@ -321,7 +330,7 @@ module.exports = { ...@@ -321,7 +330,7 @@ module.exports = {
if (!sup) if (!sup)
return res.serverError("Supervisor created but returned null"); return res.serverError("Supervisor created but returned null");
sendConfirmationMail(sup, (err) => { sendConfirmationMail(sup, password, (err) => {
if (err) throw err; if (err) throw err;
return res.ok(); return res.ok();
}); });
......
/* global Student, StuSup, sails */ /* global Student, StuSup, sails */
const bcrypt = require('bcrypt-nodejs'); const bcrypt = require('bcrypt-nodejs');
var _ = require('lodash');
/** /**
* @class Student * @class Student
...@@ -60,7 +61,7 @@ module.exports = { ...@@ -60,7 +61,7 @@ module.exports = {
lang: { lang: {
columnName: 'lang', columnName: 'lang',
type: 'string', type: 'string',
size: 2 size: 5
}, },
id_active_scene: { id_active_scene: {
columnName: 'id_active_scene', columnName: 'id_active_scene',
...@@ -630,6 +631,36 @@ module.exports = { ...@@ -630,6 +631,36 @@ module.exports = {
.catch(err => {throw err}); .catch(err => {throw err});
}) })
.catch(err => {cb(err, null)}); .catch(err => {cb(err, null)});
},
/**
* Generates a new username using name and surname
*/
genUsername: function(name, surname, callback) {
var prefix = (name + ' ' + surname).split(/\s+/).map(x => {return x.toLowerCase()[0]}).join('');
var counter = 0;
var found = true;
async.doWhilst(
function (cb) {
counter = counter + 1;
Student.findOne({username: prefix + counter})
.then((l) => {
if (!l)
found = false;
cb();
})
.catch((err) => {
found = false;
cb();
});
},
function () {
return found;
},
function () {
callback(prefix + counter);
}
);
} }
}; };
...@@ -249,6 +249,7 @@ ...@@ -249,6 +249,7 @@
"msg_change_password": "Please enter a new password for your account:", "msg_change_password": "Please enter a new password for your account:",
"msg_request_change_password": "Enter your email to request for a password change. An e-mail will be sent to access password change form.", "msg_request_change_password": "Enter your email to request for a password change. An e-mail will be sent to access password change form.",
"name": "Name", "name": "Name",
"name_invalid": "Invalid name",
"new_img": "New image", "new_img": "New image",
"new_instruction": "New instruction", "new_instruction": "New instruction",
"new_method": "New method", "new_method": "New method",
...@@ -409,7 +410,8 @@ ...@@ -409,7 +410,8 @@
"state_spontaneous": "Spontaneous", "state_spontaneous": "Spontaneous",
"state_supervised": "Supervised", "state_supervised": "Supervised",
"stop": "Stop", "stop": "Stop",
"student_account_confirm": "The new account is now available from the students list.", "student_existing_confirm": "The student's account is now available from the students list below.",
"student_new_confirm": "The new account for <b>{{ name }} {{ surname }}</b>, with serial number <tt>{{ serial }}</tt> and credential username <tt>{{ username }}</tt>, is now available from the students list. <br> Please, set password for this new account in its <a href=\"/app/#/student/{{ id_stu }}/setup\">configuration section</a>.",
"student_added": "Student added", "student_added": "Student added",
"student_already_exists": "A student with that username already exists, please try with another one", "student_already_exists": "A student with that username already exists, please try with another one",
"student_already_linked": "The student is already linked to your account", "student_already_linked": "The student is already linked to your account",
...@@ -438,6 +440,7 @@ ...@@ -438,6 +440,7 @@
"supervisors": "Supervisors", "supervisors": "Supervisors",
"support": "User support", "support": "User support",
"surname": "Surname", "surname": "Surname",
"surname_invalid": "Invalid surname",
"tag_deleted": "Tag deleted", "tag_deleted": "Tag deleted",
"tape_background": "Tape background", "tape_background": "Tape background",
"template_deleted": "Template deleted", "template_deleted": "Template deleted",
......
...@@ -248,6 +248,7 @@ ...@@ -248,6 +248,7 @@
"msg_change_password": "Por favor, introduzca la nueva clave para su cuenta:", "msg_change_password": "Por favor, introduzca la nueva clave para su cuenta:",
"msg_request_change_password": "Introduzca su correo electrónico para solicitar el cambio de clave. Recibirá un correo con la dirección de acceso al formulario de cambio de clave.", "msg_request_change_password": "Introduzca su correo electrónico para solicitar el cambio de clave. Recibirá un correo con la dirección de acceso al formulario de cambio de clave.",
"name": "Nombre", "name": "Nombre",
"name_invalid": "Nombre inválido",
"new_img": "Nueva imagen", "new_img": "Nueva imagen",
"new_instruction": "Nueva instrucción", "new_instruction": "Nueva instrucción",
"new_method": "Nuevo método", "new_method": "Nuevo método",
...@@ -407,7 +408,8 @@ ...@@ -407,7 +408,8 @@
"state_spontaneous": "Espontáneo", "state_spontaneous": "Espontáneo",
"state_supervised": "Guiado", "state_supervised": "Guiado",
"stop": "Parar", "stop": "Parar",
"student_account_confirm": "La nueva cuenta ahora está disponible en su lista de alumnos.", "student_existing_confirm": "La nueva cuenta de estudiante ahora está disponible en su lista de alumnos, abajo.",
"student_new_confirm": "La cuenta para <b>{{ name }} {{ surname }}</b>, con número de serie <tt>{{ serial }}</tt> y credencial de usuario <tt>{{ username }}</tt>, está ya disponible en su lista de estudiantes. <br>Por favor, establezca la contraseña para la nueva cuenta en la <a href=\"/app/#/student/{{ id_stu }}/setup\">sección de configuración</a> de la misma.",
"student_added": "Estudiante añadido", "student_added": "Estudiante añadido",
"student_already_exists": "Ya existe un estudiante con ese nombre de usuario. Por favor, inténtelo de nuevo con algo diferente.", "student_already_exists": "Ya existe un estudiante con ese nombre de usuario. Por favor, inténtelo de nuevo con algo diferente.",
"student_already_linked": "El estudiante ya está vinculado a su cuenta", "student_already_linked": "El estudiante ya está vinculado a su cuenta",
...@@ -436,6 +438,7 @@ ...@@ -436,6 +438,7 @@
"support": "Atención al cliente", "support": "Atención al cliente",
"supervisors": "Supervisores", "supervisors": "Supervisores",
"surname": "Apellidos", "surname": "Apellidos",
"surname_invalid": "Apellidos inválidos",
"tag_deleted": "Etiqueta borrada", "tag_deleted": "Etiqueta borrada",
"tape_background": "Fondo de la cinta", "tape_background": "Fondo de la cinta",
"template_deleted": "Plantilla eliminada", "template_deleted": "Plantilla eliminada",
......
...@@ -100,15 +100,12 @@ function LoginCtrl( ...@@ -100,15 +100,12 @@ function LoginCtrl(
var formdata_empty = { var formdata_empty = {
name: '', name: '',
surname: '',
email: '', email: '',
password: '',
password_confirm: '',
lang: '', lang: '',
role: '', role: '',
}; };
$scope.minlength = CONSTANTS.password_minlength;
/* Forms objects */ /* Forms objects */
$scope.forms = {}; $scope.forms = {};
...@@ -142,13 +139,13 @@ $scope.signup = function (formName) { ...@@ -142,13 +139,13 @@ $scope.signup = function (formName) {
return; return;
} }
if ($scope.formdata.password.length < CONSTANTS.password_minlength) { if (typeof $scope.formdata.name == 'undefined' || form.name.$invalid) {
ngToast.danger($translate.instant('password_short', {minlength: CONSTANTS.password_minlength})); ngToast.danger($translate.instant('name_invalid'));
return; return;
} }
if ($scope.formdata.password !== $scope.formdata.password_confirm) { if ($scope.formdata.role != "office" && (typeof $scope.formdata.surname == 'undefined' || form.surname.$invalid )) {
ngToast.danger($translate.instant('password_match')); ngToast.danger($translate.instant('surname_invalid'));
return; return;
} }
......
...@@ -152,25 +152,21 @@ ...@@ -152,25 +152,21 @@
<img src="img/parents.png" alt="{{'parents_tutor' | translate}}" title="{{'parents_tutor' | translate}}" /> <img src="img/parents.png" alt="{{'parents_tutor' | translate}}" title="{{'parents_tutor' | translate}}" />
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<input type="hidden" ng-model="formdata.role" value="tutor"></input> <input type="hidden" ng-model="formdata.role" value="tutor"></input>
<label translate>name</label>
<div class="form-group"> <div class="form-group">
<label translate>email</label> <input type="text" class="form-control" name="name" placeholder="{{ 'name' | translate }}" ng-model="formdata.name" required/>
<div class="form-group"> </div>
<input type="email" class="form-control" name="email" placeholder="{{ 'email' | translate }}" ng-model="formdata.email"/> <label translate>surname</label>
<span class="color_red text_sm pull-right" ng-show="forms.tutorForm.email.$dirty && forms.tutorForm.email.$invalid" translate>email_invalid</span> <div class="form-group">
</div> <input type="text" class="form-control" name="surname" placeholder="{{ 'surname' | translate }}" ng-model="formdata.surname" required/>
</div>
<label translate>email</label>
<div class="form-group">
<input type="email" class="form-control" name="email" placeholder="{{ 'email' | translate }}" ng-model="formdata.email"/>
<span class="color_red text_sm pull-right" ng-show="forms.tutorForm.email.$dirty && forms.tutorForm.email.$invalid" translate>email_invalid</span>
</div> </div>
<fieldset>
<label translate>password</label>
<div class="form-group">
<input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" name="password" required ng-model="formdata.password"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.tutorForm.password.$dirty && forms.tutorForm.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div>
<div class="form-group">
<input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" required ng-model="formdata.password_confirm"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.tutorForm.password.$dirty && forms.tutorForm.password_confirm.$dirty" translate>password_match</span>
</div>
</fieldset>
<div class="form-group"> <div class="form-group">
<input type="checkbox" ng-model="formdata.disclaimer_accepted"> <input type="checkbox" ng-model="formdata.disclaimer_accepted">
<span translate>disclaimer_accept</span> <span translate>disclaimer_accept</span>
...@@ -208,26 +204,26 @@ ...@@ -208,26 +204,26 @@
<img src="img/therapist.png" alt="{{'therapist' | translate}}" title="{{'therapist' | translate}}" /> <img src="img/therapist.png" alt="{{'therapist' | translate}}" title="{{'therapist' | translate}}" />
</div> </div>
<div class="form-group col-md-4" id="tutor_form"> <div class="form-group col-md-4" id="tutor_form">
<input type="hidden" ng-model="formdata.role" value="therapist"></input>
<label translate>name</label>
<div class="form-group">
<input type="text" class="form-control" name="name" placeholder="{{ 'name' | translate }}" ng-model="formdata.name" required/>
</div>
<label translate>surname</label>
<div class="form-group">
<input type="text" class="form-control" name="surname" placeholder="{{ 'surname' | translate }}" ng-model="formdata.surname" required/>
</div>
<label translate>email</label>
<div class="form-group"> <div class="form-group">
<label translate>email</label>
<input type="email" class="form-control" name="email" placeholder="{{ 'email' | translate }}" ng-model="formdata.email"/> <input type="email" class="form-control" name="email" placeholder="{{ 'email' | translate }}" ng-model="formdata.email"/>
<span class="color_red text_sm pull-right" ng-show="forms.therapistForm.email.$dirty && forms.therapistForm.email.$invalid" translate>email_invalid</span> <span class="color_red text_sm pull-right" ng-show="forms.theraphistForm.email.$dirty && forms.theraphistForm.email.$invalid" translate>email_invalid</span>
</div> </div>
<fieldset>
<label translate>password</label>
<div class="form-group">
<input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" name="password" required ng-model="formdata.password"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.therapistForm.password.$dirty && forms.therapistForm.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div>
<div class="form-group">
<input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" required ng-model="formdata.password_confirm"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.therapistForm.password.$dirty && forms.therapistForm.password_confirm.$dirty" translate>password_match</span>
</div>
</fieldset>
<div class="form-group"> <div class="form-group">
<input type="checkbox" ng-model="formdata.disclaimer_accepted"> <input type="checkbox" ng-model="formdata.disclaimer_accepted">
<span translate>disclaimer_accept</span> <span translate>disclaimer_accept</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label>Captcha</label> <label>Captcha</label>
<div vc-recaptcha></div> <div vc-recaptcha></div>
...@@ -259,26 +255,16 @@ ...@@ -259,26 +255,16 @@
<img src="img/office.jpg" alt="{{'office_center' | translate}}" title="{{'office_center' | translate}}" /> <img src="img/office.jpg" alt="{{'office_center' | translate}}" title="{{'office_center' | translate}}" />
</div> </div>
<div class="form-group col-md-4" id="office_form"> <div class="form-group col-md-4" id="office_form">
<input type="hidden" ng-model="formdata.role" value="office"></input>
<label translate>name</label>
<div class="form-group"> <div class="form-group">
<label translate>name</label> <input type="text" class="form-control" name="name" placeholder="{{ 'name' | translate }}" ng-model="formdata.name" required/>
<input type="text" class="form-control" placeholder="{{ 'name' | translate }}" name="name" required ng-model="formdata.name"/>
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate>email</label> <label translate>email</label>
<input type="email" class="form-control" placeholder="{{ 'email' | translate }}" name="email" required ng-model="formdata.email"/> <input type="email" class="form-control" placeholder="{{ 'email' | translate }}" name="email" required ng-model="formdata.email"/>
<span class="color_red text_sm pull-right" ng-show="forms.officeForm.email.$dirty && forms.officeForm.email.$invalid" translate>email_invalid</span> <span class="color_red text_sm pull-right" ng-show="forms.officeForm.email.$dirty && forms.officeForm.email.$invalid" translate>email_invalid</span>
</div> </div>
<fieldset>
<label translate>password</label>
<div class="form-group">
<input type="password" class="form-control" id="signin_password1" placeholder="{{ 'password_type' | translate }}" name="password" required ng-model="formdata.password"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.officeForm.password.$dirty && forms.officeForm.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div>
<div class="form-group">
<input type="password" class="form-control" id="signin_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" required ng-model="formdata.password_confirm"/>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.officeForm.password.$dirty && forms.officeForm.password_confirm.$dirty" translate>password_match</span>
</div>
</fieldset>
<div class="form-group"> <div class="form-group">
<input type="checkbox" ng-model="formdata.disclaimer_accepted"> <input type="checkbox" ng-model="formdata.disclaimer_accepted">
<span translate>disclaimer_accept</span> <span translate>disclaimer_accept</span>
......
...@@ -57,11 +57,11 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl( ...@@ -57,11 +57,11 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
$scope.showForm = function () { $scope.showForm = function () {
// Reset the form // Reset the form
$scope.formdata = { $scope.formdata = {
username: '', name: '',
password: '', password: '',
password_confirm: '', password_confirm: '',
name: $translate.instant('name'), name: '',
surname: $translate.instant('surname'), surname: '',
birthdate: Date(), birthdate: Date(),
country: 'ES', country: 'ES',
gender: 'M', gender: 'M',
...@@ -94,6 +94,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl( ...@@ -94,6 +94,7 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
$http.post(config.backend + '/stu/license/sup/' + $rootScope.user.id, {license: $scope.formdata.license_number}) $http.post(config.backend + '/stu/license/sup/' + $rootScope.user.id, {license: $scope.formdata.license_number})
.success(function (data) { .success(function (data) {
loadStudents(); loadStudents();
$scope.confirmation_msg = $translate.instant('student_existing_confirm');
$scope.slide.rightTo('confirmation'); $scope.slide.rightTo('confirmation');
}) })
.error(function (err) { .error(function (err) {
...@@ -118,18 +119,20 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl( ...@@ -118,18 +119,20 @@ dashboardControllers.controller('StudentsCtrl', function StudentsCtrl(
$scope.addNew = function (type) { $scope.addNew = function (type) {
// set language according to interface settings // set language according to interface settings
$scope.formdata.lang = $translate.use(); $scope.formdata.lang = $rootScope.user.lang;
// Validate password match
if ($scope.formdata.password_confirm.length && $scope.formdata.password !== $scope.formdata.password_confirm) {
ngToast.danger($translate.instant('password_match'));
return;
}
// 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) {
loadStudents(); loadStudents();
$scope.confirmation_msg = $translate.instant('student_new_confirm',
{
name: data.name,
surname: data.surname,
username: data.username,
serial: data.license.number,
id_stu: data.id,
});
$scope.slide.rightTo('confirmation'); $scope.slide.rightTo('confirmation');
}) })
.error(function (err) { .error(function (err) {
......
...@@ -96,17 +96,12 @@ ...@@ -96,17 +96,12 @@
</div> </div>
<div class="form-group col-md-4"> <div class="form-group col-md-4">
<div class="form-group"> <div class="form-group">
<label translate>username</label> <label translate>name</label>
<input type="username" class="form-control" id="setup_username" placeholder="{{ 'username_default' | translate }}" required ng-model="formdata.username" /> <input type="text" class="form-control" id="setup_name" placeholder="{{ 'name' | translate }}" required ng-model="formdata.name" />
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate>password</label> <label translate>surname</label>
<input type="password" class="form-control" id="setup_password1" placeholder="{{ 'password_new_type' | translate }}" name="password" ng-model="formdata.password" required /> <input type="text" class="form-control" id="setup_surname" placeholder="{{ 'surname' | translate }}" required ng-model="formdata.surname" />
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.new.password.$dirty && forms.new.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div>
<div class="form-group">
<input type="password" class="form-control" id="setup_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" ng-model="formdata.password_confirm" required />
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.new.password.$dirty && forms.new.password_confirm.$dirty" translate>password_match</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<label translate>license_number</label> <label translate>license_number</label>
...@@ -140,17 +135,12 @@ ...@@ -140,17 +135,12 @@
</div> </div>
<div class="form-group col-md-4" id="office_form"> <div class="form-group col-md-4" id="office_form">
<div class="form-group"> <div class="form-group">
<label translate>username</label> <label translate>name</label>
<input type="username" class="form-control" id="setup_username" placeholder="{{ 'username_default' | translate }}" required ng-model="formdata.username" /> <input type="text" class="form-control" id="setup_name" placeholder="{{ 'name' | translate }}" required ng-model="formdata.name" />
</div>
<div class="form-group">
<label translate>password</label>
<input type="password" class="form-control" id="setup_password1" placeholder="{{ 'password_new_type' | translate }}" name="password" ng-model="formdata.password" required />
<span class="color_red text_sm pull-right" ng-show="formdata.password.length < minlength && forms.test.password.$dirty && forms.test.password_confirm.$dirty"> {{ 'password_short' | translate:'{ minlength: minlength }' }}</span>
</div> </div>
<div class="form-group"> <div class="form-group">
<input type="password" class="form-control" id="setup_password2" placeholder="{{ 'password_confirm' | translate }}" name="password_confirm" ng-model="formdata.password_confirm" required /> <label translate>surname</label>
<span class="color_red text_sm pull-right" ng-show="formdata.password != formdata.password_confirm && forms.test.password.$dirty && forms.test.password_confirm.$dirty" translate>password_match</span> <input type="text" class="form-control" id="setup_surname" placeholder="{{ 'surname' | translate }}" required ng-model="formdata.surname" />
</div> </div>
</div> </div>
</div> </div>
...@@ -173,7 +163,7 @@ ...@@ -173,7 +163,7 @@
<div ng-class="slide.back ? 'switch-animation-back' : 'switch-animation'" ng-switch-when="confirmation"> <div ng-class="slide.back ? 'switch-animation-back' : 'switch-animation'" ng-switch-when="confirmation">
<h2>{{ 'account_available' | translate }} </h2> <h2>{{ 'account_available' | translate }} </h2>
<p translate>student_account_confirm</p> <p ng-bind-html="confirmation_msg"></p>
<br> <br>
<img src="img/child.png"/> <img src="img/child.png"/>
......
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
"notification_from_pictogram": "Notification from Pictogram", "notification_from_pictogram": "Notification from Pictogram",
"no_name": "No name", "no_name": "No name",
"no_surname": "No surname", "no_surname": "No surname",
"office_link": "The office/center \"{{ name }}\" with email \"{{ email }}\" has added you as part of its team in Pictogram.", "office_link": "The office/center \"{{{ name }}}\" with email \"{{{ email }}}\" has added you as part of its team in Pictogram.",
"signin_mail": "To activate your Pictogram account, click on this link:\n", "signin_mail": "To activate your Pictogram account, first click on this link:\n {{{ url }}} \nAccess with your email and the following password:\n {{{ password }}}\nWe recommend to change your password as soon as possible.",
"student_unlinked": "You have lost the link to the student \"{{ name }} {{ surname }}\", with license number \"{{ license }}\".", "student_unlinked": "You have lost the link to the student \"{{{ name }}} {{{ surname }}}\", with license number \"{{{ license }}}\".",
"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": "Welcome", "Welcome": "Welcome",
"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"
} }
...@@ -5,12 +5,12 @@ ...@@ -5,12 +5,12 @@
"notification_from_pictogram": "Notificación desde Pictogram", "notification_from_pictogram": "Notificación desde Pictogram",
"no_name": "Sin nombre", "no_name": "Sin nombre",
"no_surname": "Sin apellidos", "no_surname": "Sin apellidos",
"office_link": "El centro/gabinete \"{{ name }}\", con correo electrónico \"{{ email }}\" le ha añadido como parte de su equipo.", "office_link": "El centro/gabinete \"{{{ name }}}\", con correo electrónico \"{{{ email }}}\" le ha añadido como parte de su equipo.",
"signin_mail": "Para activar su cuenta en Pictogram, haga click en el siguiente enlace:\n", "signin_mail": "Para activar su cuenta en Pictogram, primero haga click en el siguiente enlace:\n {{{ url }}} \nAcceda con su correo y la contraseña siguiente:\n {{{ password }}}\nLe recomendamos modificar la contraseña tan pronto acceda al sistema.",
"student_unlinked": "Se ha desvinculado de la cuenta de estudiante \"{{ name }} {{ surname }}\", con número de licencia \"{{ license }}\".", "student_unlinked": "Se ha desvinculado de la cuenta de estudiante \"{{{ name }}} {{{ surname }}}\", con número de licencia \"{{{ license }}}\".",
"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": "Bienvenido", "Welcome": "Bienvenido",
"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"
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
"jsonwebtoken": "~0.4.0", "jsonwebtoken": "~0.4.0",
"lodash": "^3.10.1", "lodash": "^3.10.1",
"moment": "^2.18.1", "moment": "^2.18.1",
"password-generator": "^2.1.0",
"rc": "~0.5.0", "rc": "~0.5.0",
"sails": "^0.12.3", "sails": "^0.12.3",
"sails-disk": "~0.10.0", "sails-disk": "~0.10.0",
......
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