/* (1) Load professors ---------------------------------------------------------*/ /* (1) Initialize list */ gstore.add('professors', []); /* (2) Get professors */ api.call('GET professor/1/', { vh: true }, function(rs){ // {1} If error -> abort // if( rs.error !== 0 )return console.log('No professor found, error: '+rs.error); console.log(rs); // {2} Store professors // gstore.get.professors = rs.professors; }); /* (2) Load categories (for creating a professor) ---------------------------------------------------------*/ /* (1) Initialize list */ gstore.add('categories', []); /* (2) Get categories */ api.call('GET category', { vh: true }, function(rs){ // {1} If error -> abort // if( rs.error !== 0 )return console.log('No categorie found, error: '+rs.error); console.log(rs); // {2} Store categories // gstore.get.categories = rs.categories; }); /* (2) Define filters' callback ---------------------------------------------------------*/ /* (1) Define global callback */ gstore.add('filter_handler', function(){ var request = {}; /* (1) Get all filter types */ var filter_type = Object.keys(gstore.get.filters); /* (2) Get all formated filter data */ for( ftype of filter_type ){ // 1. Initialize result filter request[ftype] = []; var fl = gstore.get.filters[ftype].length; // 2. Add only @code for @active entries for( var f = 1 ; f < fl ; f++ ){ // 2.1. Store filter locally (for easier access) var filter = gstore.get.filters[ftype][f]; // 2.2. If active -> add to list ( filter.code != null && filter.active ) && request[ftype].push(filter.code); } } /* (3) Get professor id for matching filter */ api.call('POST professor/filter', request, function(rs){ // 1. Display all on error if( rs.error !== 0 ) rs.matches = gstore.get.professors.map(function(prof,i){ return i; }); console.log(rs); // 2. Fetch professor elements var local_ptr = gstore.get.professors; var l = gstore.get.professors.length; // 3. For each element for( var e = 0 ; e < l ; e++ ){ // 3.1. Show by default var element = document.querySelector('section[data-id=\''+local_ptr[e].idProfesseur+'\']'); if( !element ) continue; element.remClass('filter-hidden'); // 3.2. Only hide if does not match filter if( rs.matches.indexOf(local_ptr[e].idProfesseur) <= -1 ) element.addClass('filter-hidden'); } }); }); /* (3) Get Filters ---------------------------------------------------------*/ /* (1) Define global filter */ gstore.add('filters', { categories: [{ visible: false, active: [] }], formations: [{ visible: false, active: [] }], ues: [{ visible: false, active: [] }] }); /* (2) Define filter group show/hide */ gstore.add('show_fgroup', function(gname){ var opened = gstore.get.filters[gname] != null && gstore.get.filters[gname][0].visible; // {1} hide all by default// for( var f in gstore.get.filters ) gstore.get.filters[f][0].visible = false; // {2} If wrong @gname -> abort // if( gstore.get.filters[gname] == null ) return; // {3} Show selected filter // gstore.get.filters[gname][0].visible = !opened; }); /* (3) Define filter item toggle */ gstore.add('toggle_filter', function(gname, i){ // {1} If wrong @gname -> abort // if( gstore.get.filters[gname] == null ) return; // {2} If wrong @i -> abort // if( gstore.get.filters[gname][i] == null ) return; // {3} Toggle filter activation // gstore.get.filters[gname][i].active = !gstore.get.filters[gname][i].active; // {4} Update active table // gstore.get.filters[gname][0].active.splice(0); for( var f = 1 ; f < gstore.get.filters[gname].length ; f++ ) if( gstore.get.filters[gname][f].active ) gstore.get.filters[gname][0].active.push(f); }); /* (4) Get Formations */ api.call('GET formation', {}, function(rs){ // {1} If error -> abort // if( rs.error !== 0 ) return console.log('No formation found, error: '+rs.error); console.log(rs); // {2} Format UE filters // for( var i = 0 ; i < rs.formations.length ; i++ ) gstore.get.filters.formations.push({ code: rs.formations[i].idForm, name: rs.formations[i].labelForm, active: false }); }); /* (5) Get UEs */ api.call('GET ue', {}, function(rs){ // {1} If error -> abort // if( rs.error !== 0 ) return console.log('No UE found, error: '+rs.error); console.log(rs); // {2} Format UE filters // for( var i = 0 ; i < rs.ues.length ; i++ ) gstore.get.filters.ues.push({ code: rs.ues[i].code, name: rs.ues[i].label, active: false }); }); /* (6) Get professor categories */ api.call('GET category', {}, function(rs){ // {1} If error -> abort // if( rs.error !== 0 ) return console.log('No category found, error: '+rs.error); console.log(rs); // {2} Format category filters // for( var i = 0 ; i < rs.categories.length ; i++ ) gstore.get.filters.categories.push({ code: rs.categories[i].idCategorie, name: rs.categories[i].labelCategorie, active: false }); }); /* (4) Manage Instant Search (IS) ---------------------------------------------------------*/ /* (1) Define global timeout index */ gstore.add('is_to', null); /* (2) Define search value buffer */ gstore.add('is_buf', null); /* (3) Define instant search function */ gstore.add('is_handler', function(e){ /* (1) Remove last timeout */ if( gstore.get.is_to != null ) clearTimeout(gstore.get.is_to); /* (2) Store value in buffer */ gstore.get.is_buf = e.target.value.trim().toLowerCase(); /* (3) Launch timeout (wait 1s) before filtering */ gstore.get.is_to = setTimeout(function(){ // 1. Fetch elements var local_ptr = gstore.get.professors; var l = gstore.get.professors.length; // 2. For each element for( var e = 0 ; e < l ; e++ ){ // 2.1. Show by default var element = document.querySelector('section[data-id=\''+local_ptr[e].idProfesseur+'\']'); if( !element ) continue; element.remClass('search-hidden'); // 2.2. Extract name components var fname = local_ptr[e].firstName.trim().toLowerCase(); var lname = local_ptr[e].lastName.trim().toLowerCase(); var fullname = fname+' '+lname; // 2.3. Hide if does not match var match_offset = gstore.get.is_buf.length == 0 || fname.search(gstore.get.is_buf) + lname.search(gstore.get.is_buf) + fullname.search(gstore.get.is_buf); if( match_offset <= -3 ) element.addClass('search-hidden'); } }, 250); }); /* (5) Manage instant create ---------------------------------------------------------*/ /* (1) Initialize toggle show */ gstore.add('create_card', false); /* (2) Initialize inputs */ gstore.add('create_cat', '-'); gstore.add('create_name', ''); gstore.add('create_cas', ''); gstore.add('create_h', ''); /* (3) Initialize error message */ gstore.add('create_err_valid', false); gstore.add('create_err', ''); /* (4) Define create handler */ gstore.add('ic_handler', function(prof_id){ /* (4.1) Trim text input */ gstore.get.create_name = gstore.get.create_name.trim(); gstore.get.create_cas = gstore.get.create_cas.trim().toLowerCase(); gstore.get.create_h = gstore.get.create_h.trim(); /* (4.2) Store values locally */ var cat = gstore.get.create_cat; var name = gstore.get.create_name.split(' '); var cas = gstore.get.create_cas; var hour = gstore.get.create_h; /* (4.3) Init client-side check */ var errors = []; /* (4.3.1) Check category */ if( isNaN(cat) ) errors.push('La catégorie de l\'enseignant est manquante'); /* (4.3.2) Check name */ if( name.length !== 2 || name[0].length < 2 || name[1].length < 2 ) errors.push('Le nom doit suivre le format "Prénom Nom"'); /* (4.3.3) Check CAS login */ if( !/^([a-z]{4,16})?$/.test(cas) ) errors.push('L\'identifiant doit être vide ou comprendre de 4 à 16 lettres'); /* (4.3.4) Check hours */ if( hour === '' || isNaN(hour) || hour < 0 ) errors.push('Le nombre d\'heures doit être un entier positif.'); /* (4.4) Show first error only (for 2s) */ if( errors.length > 0 ){ gstore.get.create_err = errors[0]; return setTimeout(() => gstore.add('create_err', ''), 2000); } /* (4.5.1) Création de la requête */ var rq = { firstName: name[0], lastName: name[1], category: cat, initials: name[0].substr(0,2)+name[1].substr(0,2), hoursToDo: hour, isAdmin: false }; // optional cas_login if( cas.length > 0 ) rq.casLogin = cas; /* (4.5.2) Send request */ api.call('POST professor', rq, function(rs){ console.log(rs); /* (4.5.2.1) Manage 'already exist' error */ if( rs.error == 29 ){ gstore.get.create_err = 'Le couple Nom-Prénom est déja utilisé.'; return setTimeout(() => gstore.add('create_err', ''), 2000); } /* (4.5.2.2) Manage other errors */ if( rs.error !== 0 ){ gstore.get.create_err = 'erreur ('+rs.error+') Impossible de créer l\'enseignant'; return setTimeout(() => gstore.add('create_err', ''), 2000); } /* (4.5.2.3) Show that user is created */ // display all is ok gstore.add('create_err_valid', true); gstore.add('create_err', 'L\'enseignant a été créé, il s\'affichera au prochain rechargement'); // empty fields gstore.get.create_cat = '-'; gstore.get.create_name = ''; gstore.get.create_cas = ''; gstore.get.create_h = ''; return setTimeout(() => { gstore.add('create_err', ''); gstore.add('create_err_valid', false); }, 2000); }); }); /* (6) Manage instant remove ---------------------------------------------------------*/ /* (1) Define remove handler */ gstore.add('ir_handler', function(prof_id){ /* (1) Abort if wrong prof_id */ if( prof_id == null || isNaN(prof_id) ) return; /* (2.1) Find index in gstore */ var gi = gstore.get.professors.map( (data, i) => { return ( data.idProfesseur && data.idProfesseur == prof_id ) ? i : ''; }).join(''); /* (2.2) Exit if not found */ if( isNaN(gi) ) return; var local = gstore.get.professors[gi]; /* (3) Show popup */ (new Promise( (resolve, reject) => { popup.ask({ title: 'Confirmation de suppression', content: "La suppression de l'enseignant "+local.firstName+" "+local.lastName+" est irréversible.

Voulez-vous le supprimer définitivement ?", action: 'Supprimer', type: 'invalid' }, (popup_rs) => { popup_rs && resolve() }); /* (4) On pop-up confirmation */ })).then(function(){ return new Promise( (resolve, reject) => { /* (4.1) Delete professor */ api.call('DELETE professor/'+prof_id, {}, function(rs){ /* (4.1.1) Abort on error */ if( rs.error !== 0 || rs.deleted !== true ) return reject(rs.error); /* (4.1.2) Success */ resolve(); }); }); /* (5) On success */ }).then(function(){ /* remove from visible */ gstore.get.professors.splice(gi, 1); /* (6) On error */ }).catch(function(err_code){ popup.ask({ title: 'Error ('+err_code+')', content: 'La suppression a échouée. Veuillez réessayer ultérieurement.', action: 'OK', type: 'neutral' }, () => {}); }); }); /* (7) Manage instant edit ---------------------------------------------------------*/ /* (1) Init edit_mode */ gstore.add('edit_i', -1); /* (2) Initialize inputs */ gstore.add('edit_cat', '-'); gstore.add('edit_name', ''); gstore.add('edit_cas', ''); gstore.add('edit_h', ''); /* (3) Initialize error message */ gstore.add('edit_err_valid', false); gstore.add('edit_err', ''); /* (4) Define toggle view */ gstore.add('ie_toggle', function(prof_i){ /* (4.1) Abort if wrong prof_i */ if( prof_i == null || isNaN(prof_i) || gstore.get.professors[prof_i] == null) return gstore.add('edit_i', -1); /* (4.2) Toggle current value */ var prof = gstore.get.professors[prof_i]; /* (4.3) Pre-fill edit values */ gstore.get.edit_cat = prof.idCat; gstore.get.edit_cas = prof.casLogin; gstore.get.edit_name = prof.firstName+' '+prof.lastName; gstore.get.edit_h = prof.hoursToDo.toString(); /* (4.4) Set card to edit mode */ gstore.get.edit_i = prof_i; }); /* (5) Confirm update */ gstore.add('ie_handler', function(prof_i){ /* (5.1) Abort if wrong prof_i */ if( prof_i == null || isNaN(prof_i) || gstore.get.professors[prof_i] == null) return; /* (5.2) Toggle current value */ var prof = gstore.get.professors[prof_i]; /* (5.3) Trim text input */ gstore.get.edit_name = gstore.get.edit_name.trim(); gstore.get.edit_cas = gstore.get.edit_cas.trim().toLowerCase(); gstore.get.edit_h = gstore.get.edit_h.trim(); /* (5.4) Store values locally */ var cat = gstore.get.edit_cat; var name = gstore.get.edit_name.split(' '); var cas = gstore.get.edit_cas; var hour = gstore.get.edit_h; /* (5.5) Init client-side check */ var errors = []; /* (5.5.1) Check category */ if( isNaN(cat) ) errors.push('La catégorie de l\'enseignant est manquante'); /* (5.5.2) Check name */ if( name.length !== 2 || name[0].length < 2 || name[1].length < 2 ) errors.push('Le nom doit suivre le format "Prénom Nom"'); /* (5.5.3) Check CAS login */ if( !/^([a-z]{4,16})?$/.test(cas) ) errors.push('L\'identifiant doit être vide ou comprendre de 4 à 16 lettres'); /* (5.5.4) Check hours */ if( hour === '' || isNaN(hour) || hour < 0 ) errors.push('Le nombre d\'heures doit être un entier positif.'); /* (5.6) Show first error only (for 2s) */ if( errors.length > 0 ){ gstore.get.edit_err = errors[0]; return setTimeout(() => gstore.add('edit_err', ''), 2000); } /* (5.7) Création de la requête */ var rq = {}; ( name[0] != prof.firstName ) && ( rq.firstName = name[0] ); ( name[1] != prof.lastName ) && ( rq.lastName = name[1] ); ( cat != prof.idCat ) && ( rq.category = cat ); ( hour != prof.hoursToDo ) && ( rq.hoursToDo = hour ); ( cas != prof.casLogin ) && ( rq.casLogin = cas ); // update initials whatever have been modified (to avoid API error when no field given) rq.initials = name[0].substr(0,2) + name[1].substr(0,2); (new Promise( (resolve, reject) => { popup.ask({ title: 'Confirmation de modification', content: "La modification de l'enseignant "+prof.firstName+" "+prof.lastName+" est irréversible.

Voulez-vous le modifier ?", action: 'Modifier', type: 'search' }, (popup_rs) => { popup_rs && resolve() }); /* (5.8) On pop-up confirmation */ })).then(function(){ return new Promise( (resolve, reject) => { /* (5.8.1) Delete professor */ api.call('PUT professor/'+prof.idProfesseur, rq, function(rs){ /* (5.8.1.1) Abort on error */ if( rs.error !== 0 || rs.updated !== true ) return reject(rs.error); /* (5.8.1.2) Success */ resolve(); }); }); /* (5.9) On success */ }).then(function(){ /* (5.9.1) update VueJS element */ gstore.get.professors[prof_i].idCat = cat; gstore.get.professors[prof_i].firstName = name[0]; gstore.get.professors[prof_i].lastName = name[1]; gstore.get.professors[prof_i].casLogin = cas; gstore.get.professors[prof_i].hoursToDo = hour; /* (5.9.2) Try to set the category label */ var ci = gstore.get.filters.categories.map( (data, i) => { return ( data.code && data.code == cat ) ? i : ''; }).join(''); /* (5.9.3) Exit if not found */ if( isNaN(ci) ) return gstore.add('edit_i', -1); /* (5.9.4) If found -> set category label */ gstore.get.professors[prof_i].categorie = gstore.get.filters.categories[ci].name; /* (5.9.5) Remove edit mode */ gstore.add('edit_i', -1); /* (5.10) On error */ }).catch(function(err_code){ popup.ask({ title: 'Error ('+err_code+')', content: 'La modification a échouée. Veuillez réessayer ultérieurement.', action: 'OK', type: 'neutral' }, () => {}); }); }); /* (8) Manage instant admin ---------------------------------------------------------*/ /* (1) Define admin handler */ gstore.add('ia_handler', function(prof_i){ /* (1) Abort if wrong prof_i */ if( prof_i == null || isNaN(prof_i) || gstore.get.professors[prof_i] == null) return; /* (2) Toggle current value */ var local = gstore.get.professors[prof_i]; var is_admin = local.admin == '1' || local.admin === true; var new_state = !is_admin; /* (3.1) Update in database */ api.call('PUT professor/'+local.idProfesseur, { isAdmin: new_state }, function(rs){ /* (3.1.1) Abort on error */ if( rs.error !== 0 || rs.updated !== true ) return console.log('Impossible de changer le status \'admin\', erreur '+rs.error); /* (3.1.2) Success */ gstore.get.professors[prof_i].admin = new_state ? 1 : 0; }); });