[webpack.ue.view] no more need for $router (it is in Gstore) for navigation funcs [webpack.ue.manage] eased 'rem_form' (by index no more ID) + fetch professors / created layout for changing professor for a cours|TD|TP
This commit is contained in:
parent
8218571498
commit
cd9f342eda
|
@ -9,8 +9,8 @@
|
|||
<!-- FILTERS -->
|
||||
<section class='filter'>
|
||||
|
||||
<div>Type</div>
|
||||
<div>enseignant</div>
|
||||
<div class='null'></div>
|
||||
<div>volume horaire</div>
|
||||
<div>formations</div>
|
||||
|
||||
|
@ -21,13 +21,16 @@
|
|||
v-for='(c,i) in gstore.manage.cours'
|
||||
:data-id='c.idCours'>
|
||||
|
||||
<select v-model='c.idProf' @change='upd_prof(i)'>
|
||||
<option value='-1' v-show='c.idProf!=-1'>Aucun enseignant affecté</option>
|
||||
<option v-for='p in gstore.manage.prof' :value='p.idProfesseur' v-show='p.idProfesseur!=c.idProf'>{{ `${p.firstName} ${p.lastName}` }}</option>
|
||||
</select>
|
||||
<div>Cours</div>
|
||||
<div :data-prof='c.idProf'>{{ c.idProf ? `${c.firstName} ${c.lastName}` : 'Aucun enseignant affecté' }}</div>
|
||||
<div>{{ c.volume }}</div>
|
||||
<div class='taglist'>
|
||||
<div v-for='f in c.formations' data-action>
|
||||
<span class='tag'>{{ gstore.form_by_id(f).labelForm || '???' }}</span>
|
||||
<span data-remove @click='gstore.rem_form(0, c.idCours, f)'></span>
|
||||
<span data-remove @click='gstore.rem_form(0, i, f)'></span>
|
||||
</div>
|
||||
|
||||
<div data-action>
|
||||
|
@ -52,13 +55,16 @@
|
|||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<select v-model='td.idProf' @change='upd_prof(i)'>
|
||||
<option value='-1' v-show='td.idProf!=-1'>Aucun enseignant affecté</option>
|
||||
<option v-for='p in gstore.manage.prof' :value='p.idProfesseur' v-show='p.idProfesseur!=td.idProf'>{{ `${p.firstName} ${p.lastName}` }}</option>
|
||||
</select>
|
||||
<div>TD</div>
|
||||
<div :data-prof='td.idProf'>{{ td.idProf ? `${td.firstName} ${td.lastName}` : 'Aucun enseignant affecté' }}</div>
|
||||
<div>{{ td.volume }}</div>
|
||||
<div class='taglist'>
|
||||
<div v-for='f in td.formations' data-action>
|
||||
<span class='tag'>{{ gstore.form_by_id(f).labelForm || '???' }}</span>
|
||||
<span data-remove @click='gstore.rem_form(1, td.idTD, f)'></span>
|
||||
<span data-remove @click='gstore.rem_form(1, i, f)'></span>
|
||||
</div>
|
||||
|
||||
<div data-action>
|
||||
|
@ -83,13 +89,16 @@
|
|||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<select v-model='tp.idProf' @change='upd_prof(i)'>
|
||||
<option value='-1' v-show='tp.idProf!=-1'>Aucun enseignant affecté</option>
|
||||
<option v-for='p in gstore.manage.prof' :value='p.idProfesseur' v-show='p.idProfesseur!=tp.idProf'>{{ `${p.firstName} ${p.lastName}` }}</option>
|
||||
</select>
|
||||
<div>TP</div>
|
||||
<div :data-prof='tp.idProf'>{{ tp.idProf ? `${tp.firstName} ${tp.lastName}` : 'Aucun enseignant affecté' }}</div>
|
||||
<div>{{ tp.volume }}</div>
|
||||
<div class='taglist'>
|
||||
<div v-for='f in tp.formations' data-action>
|
||||
<span class='tag'>{{ gstore.form_by_id(f).labelForm || '???' }}</span>
|
||||
<span data-remove @click='gstore.rem_form(2, tp.idTP, f)'></span>
|
||||
<span data-remove @click='gstore.rem_form(2, i, f)'></span>
|
||||
</div>
|
||||
|
||||
<div data-action>
|
||||
|
@ -123,7 +132,14 @@
|
|||
return { gstore: gstore.get }
|
||||
},
|
||||
beforeMount(){
|
||||
gstore.get.manage_load(this.$route.params.code, this.$router);
|
||||
|
||||
/* (1) Try to load data */
|
||||
gstore.get.load_ue_groups(this.$route.params.code, 3).catch( (err) => { // try at max 3 times (200ms each) for UE to be loaded
|
||||
|
||||
/* (2) On error -> go to 'view' page */
|
||||
gstore.get.router.push('/ue/view/');
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
|
||||
<!-- if VIEW MODE -->
|
||||
<div class='footer' v-show='gstore.edit_i!=pi'>
|
||||
<button class='neutral' @click='gstore.nav_in($router, pi)'>Configurer</button>
|
||||
<button class='neutral' @click='gstore.nav_in(pi)'>Configurer</button>
|
||||
</div>
|
||||
<!-- if EDIT MODE -->
|
||||
<div class='footer' v-show='gstore.edit_i==pi'>
|
||||
|
|
|
@ -543,6 +543,7 @@ gstore.add('manage', {
|
|||
cours: [],
|
||||
td: [],
|
||||
tp: [],
|
||||
prof: []
|
||||
});
|
||||
|
||||
|
||||
|
@ -578,16 +579,18 @@ gstore.add('load_ue_groups', function(code, recur=0){
|
|||
|
||||
api.call(`GET ue/cours/${code}`, {}, function(rs){
|
||||
|
||||
// erase data
|
||||
gstore.get.manage.cours.splice(0);
|
||||
|
||||
// reject on error
|
||||
if( rs.error !== 0 || !(rs['groups'] instanceof Array) ){
|
||||
gstore.get.manage.cours.splice();
|
||||
reject({ label: 'Cours', code: rs.error});
|
||||
}
|
||||
if( rs.error !== 0 || !(rs['groups'] instanceof Array) )
|
||||
return reject({ label: 'Cours', code: rs.error});
|
||||
|
||||
// store data
|
||||
// for each field add a 'add_form' for instant-adding formations afterwards
|
||||
for( var group of rs.groups ){
|
||||
group.add_form = '-';
|
||||
( group.idProf == null ) && ( group.idProf = -1 );
|
||||
gstore.get.manage.cours.push( group );
|
||||
}
|
||||
|
||||
|
@ -603,16 +606,18 @@ gstore.add('load_ue_groups', function(code, recur=0){
|
|||
|
||||
api.call(`GET ue/td/${code}`, {}, function(rs){
|
||||
|
||||
// erase data
|
||||
gstore.get.manage.td.splice(0);
|
||||
|
||||
// reject on error
|
||||
if( rs.error !== 0 || !(rs['groups'] instanceof Array) ){
|
||||
gstore.get.manage.td.splice();
|
||||
reject({ label: 'TD', code: rs.error});
|
||||
}
|
||||
if( rs.error !== 0 || !(rs['groups'] instanceof Array) )
|
||||
return reject({ label: 'TD', code: rs.error});
|
||||
|
||||
// store data
|
||||
// for each field add a 'add_form' for instant-adding formations afterwards
|
||||
for( var group of rs.groups ){
|
||||
group.add_form = '-';
|
||||
( group.idProf == null ) && ( group.idProf = -1 );
|
||||
gstore.get.manage.td.push( group );
|
||||
}
|
||||
|
||||
|
@ -630,16 +635,18 @@ gstore.add('load_ue_groups', function(code, recur=0){
|
|||
|
||||
api.call(`GET ue/tp/${code}`, {}, function(rs){
|
||||
|
||||
// erase data
|
||||
gstore.get.manage.tp.splice(0);
|
||||
|
||||
// reject on error
|
||||
if( rs.error !== 0 || !(rs['groups'] instanceof Array) ){
|
||||
gstore.get.manage.tp.splice();
|
||||
reject({ label: 'TP', code: rs.error});
|
||||
}
|
||||
if( rs.error !== 0 || !(rs['groups'] instanceof Array) )
|
||||
return reject({ label: 'TP', code: rs.error});
|
||||
|
||||
// store data
|
||||
// for each field add a 'add_form' for instant-adding formations afterwards
|
||||
for( var group of rs.groups ){
|
||||
group.add_form = '-';
|
||||
( group.idProf == null ) && ( group.idProf = -1 );
|
||||
gstore.get.manage.tp.push( group );
|
||||
}
|
||||
|
||||
|
@ -650,6 +657,35 @@ gstore.add('load_ue_groups', function(code, recur=0){
|
|||
|
||||
});
|
||||
|
||||
/* (6) Ask for professors data */
|
||||
}).then( () => {
|
||||
|
||||
return new Promise( (resolve, reject) => {
|
||||
|
||||
// 1. if already downloaded
|
||||
if( gstore.get.manage.prof.length > 0 )
|
||||
return resolve();
|
||||
|
||||
// 2. Else fetch from database
|
||||
api.call(`GET professor/0`, {}, function(rs){
|
||||
|
||||
// erase data
|
||||
gstore.get.manage.prof.splice(0);
|
||||
|
||||
// reject on error
|
||||
if( rs.error !== 0 || !(rs['professors'] instanceof Array) )
|
||||
return reject({ label: 'Professeurs', code: rs.error});
|
||||
|
||||
// store data
|
||||
gstore.get.manage.prof = rs.professors;
|
||||
|
||||
// resolve data on success
|
||||
resolve();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
|
@ -668,35 +704,29 @@ gstore.add('nav_anim', {
|
|||
});
|
||||
|
||||
/* (2) Manage nav in */
|
||||
gstore.add('nav_in', function($router, ue_i){
|
||||
gstore.add('nav_in', function(ue_i){
|
||||
|
||||
/* (1) Abort if wrong ue_i */
|
||||
if( ue_i == null || isNaN(ue_i) || gstore.get.ues[ue_i] == null)
|
||||
return;
|
||||
|
||||
/* (2) Try to get data (Promise) */
|
||||
gstore.get.load_ue_groups(gstore.get.ues[ue_i].code).then( () => {
|
||||
/* 1. Start animation */
|
||||
gstore.get.nav_anim.in = true;
|
||||
|
||||
/* 1. Start animation */
|
||||
gstore.get.nav_anim.in = true;
|
||||
setTimeout( () => {
|
||||
|
||||
setTimeout( () => {
|
||||
/* 2. Load page */
|
||||
gstore.get.router.push(`/ue/manage/${gstore.get.ues[ue_i].code}`);
|
||||
|
||||
/* 2. Load page */
|
||||
$router.push(`/ue/manage/${gstore.get.ues[ue_i].code}`);
|
||||
|
||||
/* 3. Stop animation */
|
||||
gstore.get.nav_anim.in = false;
|
||||
|
||||
}, 500 );
|
||||
|
||||
}).catch( (err) => console.log(`[label] ${err.label} [error] ${err.code}`) );
|
||||
/* 3. Stop animation */
|
||||
gstore.get.nav_anim.in = false;
|
||||
|
||||
}, 500 );
|
||||
|
||||
});
|
||||
|
||||
/* (3) Manage nav out */
|
||||
gstore.add('nav_out', function($router){
|
||||
gstore.add('nav_out', function(){
|
||||
|
||||
/* 1. Start animation */
|
||||
gstore.get.nav_anim.out = true;
|
||||
|
@ -704,15 +734,15 @@ gstore.add('nav_out', function($router){
|
|||
setTimeout( () => {
|
||||
|
||||
/* 2. Load page */
|
||||
$router.push(`/ue/view/`);
|
||||
gstore.get.router.push(`/ue/view/`);
|
||||
|
||||
/* 3. Stop animation */
|
||||
gstore.get.nav_anim.out = false;
|
||||
|
||||
/* 4. Remove 'manage' data */
|
||||
gstore.get.manage.cours = [];
|
||||
gstore.get.manage.td = [];
|
||||
gstore.get.manage.tp = [];
|
||||
gstore.get.manage.cours.splice();
|
||||
gstore.get.manage.td.splice();
|
||||
gstore.get.manage.tp.splice();
|
||||
|
||||
}, 500 );
|
||||
|
||||
|
@ -723,30 +753,113 @@ gstore.add('nav_out', function($router){
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
/* (11) Load 'manage' page data if loaded from URL
|
||||
/* (11) Manage 'manage' formations add|rem
|
||||
---------------------------------------------------------*/
|
||||
gstore.add('manage_load', function(code, $router){
|
||||
/* (1) Remove a formation */
|
||||
gstore.add('rem_form', function(type, res_i, id_form){
|
||||
|
||||
/* (1) Try to load data */
|
||||
gstore.get.load_ue_groups(code, 3).catch( (err) => { // try at max 3 times (200ms each) for UE to be loaded
|
||||
// 1. Check params types
|
||||
if( isNaN(type) || isNaN(res_i) || isNaN(id_form) )
|
||||
return;
|
||||
|
||||
// 2. Check @type param
|
||||
if( [0,1,2].indexOf(type) == -1 )
|
||||
return;
|
||||
|
||||
// 3. extract API resource from @type
|
||||
var res = [ 'cours', 'td', 'tp' ][type];
|
||||
var resM = [ 'Cours', 'TD', 'TP' ][type];
|
||||
|
||||
// 4. Extract @resource from @res_i
|
||||
var resource = gstore.get.manage[res][res_i];
|
||||
|
||||
// 4- Manage unreachable resource
|
||||
if( resource == null )
|
||||
return;
|
||||
|
||||
// 5. Extract resource ID
|
||||
var res_id = resource[`id${resM}`];
|
||||
|
||||
// 6. Request to remove formation
|
||||
api.call(`PUT ue/${res}/${res_id}`, { rem_form: [id_form] }, (rs) => {
|
||||
|
||||
// 6.1. Manage error
|
||||
if( rs.error !== 0 || rs.updated !== true )
|
||||
return;
|
||||
|
||||
// 6.2. Get reference of data in gstore (if Cours, TD, TP)
|
||||
var local = gstore.get.manage[res];
|
||||
|
||||
// 6.3. Unset formation to remove from view
|
||||
for( var f_index in resource.formations ){ // search its index
|
||||
|
||||
// if found -> remove by index
|
||||
if( resource.formations[f_index] === id_form ){
|
||||
resource.formations.splice(f_index, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* (2) On error -> go to 'view' page */
|
||||
$router.push('/ue/view/');
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
|
||||
});
|
||||
|
||||
/* (2) Add a formation */
|
||||
gstore.add('add_form', function(type, id_res, i){
|
||||
|
||||
// 1. Check params types
|
||||
if( isNaN(type) || isNaN(id_res) || isNaN(i) )
|
||||
return;
|
||||
|
||||
// 2. Check @type param
|
||||
if( [0,1,2].indexOf(type) == -1 )
|
||||
return;
|
||||
|
||||
// 3. extract API resource from @type
|
||||
var res = [ 'cours', 'td', 'tp' ][type];
|
||||
var resM = [ 'Cours', 'TD', 'TP' ][type];
|
||||
|
||||
// 4. Exit if @i is invalid
|
||||
if( gstore.get.manage[res][i] == null )
|
||||
return;
|
||||
|
||||
// 5. Extract <select> formation id
|
||||
var id_form = gstore.get.manage[res][i].add_form;
|
||||
|
||||
// 6. Exit if not a number
|
||||
if( isNaN(id_form) )
|
||||
return;
|
||||
|
||||
// 7. Request to add formation
|
||||
api.call(`PUT ue/${res}/${id_res}`, { add_form: [id_form] }, (rs) => {
|
||||
|
||||
// 7.1. Manage error
|
||||
if( rs.error !== 0 || rs.updated !== true )
|
||||
return;
|
||||
|
||||
// 7.2. Unselect the <select>
|
||||
gstore.get.manage[res][i].add_form = '-';
|
||||
|
||||
// 7.3. Add formation to update VueJS
|
||||
gstore.get.manage[res][i].formations.push(id_form);
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* (12) Manage 'manage' formations add|rem
|
||||
/* (12) Manage 'prof' for Cours|TD|T{}
|
||||
---------------------------------------------------------*/
|
||||
/* (1) Remove a formation */
|
||||
gstore.add('rem_form', function(type, id_res, id_form){
|
||||
/* (1) Update a prof (or unset) */
|
||||
gstore.add('upd_prof', function(type, id_res, id_form){
|
||||
|
||||
// 1. Check params types
|
||||
if( isNaN(type) || isNaN(id_res) || isNaN(id_form) )
|
||||
|
@ -796,48 +909,4 @@ gstore.add('rem_form', function(type, id_res, id_form){
|
|||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
/* (2) Add a formation */
|
||||
gstore.add('add_form', function(type, id_res, i){
|
||||
|
||||
// 1. Check params types
|
||||
if( isNaN(type) || isNaN(id_res) || isNaN(i) )
|
||||
return;
|
||||
|
||||
// 2. Check @type param
|
||||
if( [0,1,2].indexOf(type) == -1 )
|
||||
return;
|
||||
|
||||
// 3. extract API resource from @type
|
||||
var res = [ 'cours', 'td', 'tp' ][type];
|
||||
var resM = [ 'Cours', 'TD', 'TP' ][type];
|
||||
|
||||
// 4. Exit if @i is invalid
|
||||
if( gstore.get.manage[res][i] == null )
|
||||
return;
|
||||
|
||||
// 5. Extract <select> formation id
|
||||
var id_form = gstore.get.manage[res][i].add_form;
|
||||
|
||||
// 6. Exit if not a number
|
||||
if( isNaN(id_form) )
|
||||
return;
|
||||
|
||||
// 7. Request to add formation
|
||||
api.call(`PUT ue/${res}/${id_res}`, { add_form: [id_form] }, (rs) => {
|
||||
|
||||
// 7.1. Manage error
|
||||
if( rs.error !== 0 || rs.updated !== true )
|
||||
return;
|
||||
|
||||
// 7.2. Unselect the <select>
|
||||
gstore.get.manage[res][i].add_form = '-';
|
||||
|
||||
// 7.3. Add formation to update VueJS
|
||||
gstore.get.manage[res][i].formations.push(id_form);
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
|
@ -22,7 +22,7 @@
|
|||
/* (1) List element */
|
||||
& > section{
|
||||
|
||||
flex: 1 1 95%;
|
||||
flex: 1 1 90%;
|
||||
|
||||
display: flex;
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
|
||||
// flex properties
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: nowrap;
|
||||
|
||||
|
@ -62,6 +62,39 @@
|
|||
&.tp:hover{ border-left-color: $form-invalid-color; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* (1.3) Select elements*/
|
||||
& > select{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
height: 1.8em;
|
||||
width: auto;
|
||||
|
||||
margin: 0;
|
||||
margin-right: 1em;
|
||||
padding: .2em .5em;
|
||||
padding-right: 1em;
|
||||
|
||||
border: 1px solid lighten($form-neutral-color, 5%);
|
||||
border-radius: 3px;
|
||||
|
||||
background: transparent url('/asset/svg/down_arrow.svg@bbbbbb') right .5em bottom .1em no-repeat;
|
||||
background-size: auto 80%;
|
||||
|
||||
color: #999;
|
||||
font-size: .8em;
|
||||
|
||||
cursor: default;
|
||||
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
justify-self: space-around;
|
||||
flex: 0 1 20em;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -94,36 +127,14 @@
|
|||
&[data-filter='up']{ background-image: url('/asset/svg/up_arrow.svg@aaaaaa'); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
& > div.null:after{ content: none; }
|
||||
|
||||
/* (3) List title */
|
||||
& > h1{
|
||||
|
||||
flex: 1 0 95%;
|
||||
|
||||
display: inline-block;
|
||||
|
||||
margin: .8em 1.2em;
|
||||
|
||||
font-size: inherit;
|
||||
color: #888;
|
||||
|
||||
}
|
||||
|
||||
/* (4) List separator */
|
||||
& > hr{
|
||||
display: block;
|
||||
position: relative;
|
||||
|
||||
margin: 1em 1.5em;
|
||||
|
||||
border: 0;
|
||||
border-bottom: 2px solid darken($bg-color, 5%);
|
||||
}
|
||||
|
||||
/* Tags color -> darker */
|
||||
.tag{
|
||||
.tag,
|
||||
& > section > select{
|
||||
color: $primary-color;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue