[webpack.ue.manage] CREATE new Cours|TD|TP implemented (with real-time feedback (push into VueJS), then updates/remove works)
This commit is contained in:
parent
861fb49846
commit
dc647f567f
|
@ -4,7 +4,31 @@
|
|||
|
||||
<div class='list container' data-anim-incoming='1' :data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<!-- <button @click='gstore.nav_out($router)'>Retour</button> -->
|
||||
<!-- CREATE -->
|
||||
<section class='cours'
|
||||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<div class='icon' @click='gstore.ccreate()'></div>
|
||||
<select v-model='gstore.ccrea.prof'>
|
||||
<option value='-1'>Aucun enseignant affecté</option>
|
||||
<option v-for='p in gstore.manage.prof' :value='p.idProfesseur'>{{ `${p.firstName} ${p.lastName}` }}</option>
|
||||
</select>
|
||||
<select v-model='gstore.ccrea.type' class='min'>
|
||||
<option value='-' disabled>Type</option>
|
||||
<option value='0'>Cours</option>
|
||||
<option value='1'>TD</option>
|
||||
<option value='2'>TP</option>
|
||||
</select>
|
||||
<input type='text' placeholder='volume' v-model='gstore.ccrea.vol'>
|
||||
|
||||
<div style='margin-left: 1em;' :class="gstore.ccrea.err.length > 0 ? (gstore.ccrea.valid ? 'warning valid' : 'warning invalid') : ''" :data-valid='gstore.ccrea.valid?1:0'>{{ gstore.ccrea.err }}</div>
|
||||
|
||||
</section>
|
||||
|
||||
<section class='filter'></section>
|
||||
|
||||
|
||||
|
||||
<!-- FILTERS -->
|
||||
<section class='filter'>
|
||||
|
@ -21,7 +45,7 @@
|
|||
v-for='(c,i) in gstore.manage.cours'
|
||||
:data-id='c.idCours'>
|
||||
|
||||
<div class='icon' @click='gstore.rem(0, i)'></div>
|
||||
<div class='icon remove' @click='gstore.rem(0, i)'></div>
|
||||
<select v-model='c.new_prof' @change='gstore.upd_prof(0, 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>
|
||||
|
@ -56,7 +80,7 @@
|
|||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<div class='icon' @click='gstore.rem(1, i)'></div>
|
||||
<div class='icon remove' @click='gstore.rem(1, i)'></div>
|
||||
<select v-model='td.new_prof' @change='gstore.upd_prof(1, 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>
|
||||
|
@ -91,7 +115,7 @@
|
|||
data-anim-incoming='1'
|
||||
:data-anim-bounce='gstore.nav_anim.out?1:0'>
|
||||
|
||||
<div class='icon' @click='gstore.rem(2, i)'></div>
|
||||
<div class='icon remove' @click='gstore.rem(2, i)'></div>
|
||||
<select v-model='tp.new_prof' @change='gstore.upd_prof(2, 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>
|
||||
|
@ -117,6 +141,10 @@
|
|||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -403,14 +403,6 @@ gstore.add('ie_handler', function(ue_i){
|
|||
if( vco === '' || isNaN(vco) || vco < 0 )
|
||||
errors.push('Le volume horaire de cours doit être un entier positif.');
|
||||
|
||||
/* (5.5.5) Check TD */
|
||||
if( vtd === '' || isNaN(vtd) || vtd < 0 )
|
||||
errors.push('Le volume horaire de TD doit être un entier positif.');
|
||||
|
||||
/* (5.5.6) Check TP */
|
||||
if( vtp === '' || isNaN(vtp) || vtp < 0 )
|
||||
errors.push('Le volume horaire de TP doit être un entier positif.');
|
||||
|
||||
/* (5.6) Show first error only (for 2s) */
|
||||
if( errors.length > 0 ){
|
||||
|
||||
|
@ -997,3 +989,100 @@ gstore.add('rem', function(type, res_i){
|
|||
|
||||
|
||||
});
|
||||
|
||||
|
||||
/* (2) Create a Cours|TD|TP */
|
||||
gstore.add('ccrea', {
|
||||
type: '-',
|
||||
prof: -1,
|
||||
vol: '',
|
||||
err: '',
|
||||
valid: false
|
||||
});
|
||||
|
||||
gstore.add('ccreate', function(){
|
||||
|
||||
/* (1) Trim text input */
|
||||
gstore.get.ccrea.vol = gstore.get.ccrea.vol.trim();
|
||||
|
||||
/* (2) Store values locally */
|
||||
var type = gstore.get.ccrea.type;
|
||||
var prof = gstore.get.ccrea.prof;
|
||||
var vol = gstore.get.ccrea.vol;
|
||||
|
||||
/* (2) Init client-side check */
|
||||
var errors = [];
|
||||
|
||||
/* (2.1) Check type */
|
||||
if( isNaN(type) || [0,1,2].indexOf(parseInt(type)) <= -1 )
|
||||
errors.push('Le type de prestation est manquant (Cours, TD, TP)');
|
||||
|
||||
/* (2.2) Check prof */
|
||||
if( isNaN(prof) )
|
||||
errors.push('L\'enseignant est invalide ou manquant');
|
||||
|
||||
/* (2.3) Check volume */
|
||||
if( vol === '' || isNaN(vol) || vol < 0 )
|
||||
errors.push('Le volume horaire doit être un entier positif.');
|
||||
|
||||
/* (2.4) Show first error only (for 2s) */
|
||||
if( errors.length > 0 ){
|
||||
|
||||
gstore.get.ccrea.valid = false;
|
||||
gstore.get.ccrea.err = errors[0];
|
||||
|
||||
return setTimeout(() => gstore.add('ccrea.err', ''), 2000);
|
||||
|
||||
}
|
||||
|
||||
/* (3) Extract resource type */
|
||||
var restyp = ['cours', 'td', 'tp'][type];
|
||||
var restyp2 = ['Cours', 'TD', 'TP'][type];
|
||||
|
||||
/* (4) Create request */
|
||||
var rq = {
|
||||
code: gstore.get.URI[2],
|
||||
volume: parseInt(vol)
|
||||
};
|
||||
|
||||
// optional 'idProf'
|
||||
( prof > -1 ) && ( rq.idProf = parseInt(prof) );
|
||||
|
||||
|
||||
/* (5) Send request */
|
||||
api.call(`POST ue/${restyp}`, rq, function(rs){
|
||||
|
||||
console.log(rs);
|
||||
|
||||
/* (5.1) Manage errors */
|
||||
if( rs.error !== 0 ){
|
||||
gstore.get.ccrea.valid = false
|
||||
gstore.get.create_err = `erreur (${rs.error}) Impossible de créer le ${restyp}`;
|
||||
return setTimeout(() => gstore.add('create_err', ''), 2000);
|
||||
}
|
||||
|
||||
/* (5.2) Show that Cours|TD|TP is created */
|
||||
gstore.get.ccrea.valid = true;
|
||||
gstore.get.ccrea.err = `Le ${restyp} a bien été créé, rechargez la page pour le visualiser.`;
|
||||
setTimeout(() => gstore.add('create_err', ''), 2000);
|
||||
|
||||
/* (5.3) Empty fields */
|
||||
// empty fields
|
||||
gstore.get.ccrea.prof = -1;
|
||||
gstore.get.ccrea.type = '-';
|
||||
gstore.get.ccrea.vol = '';
|
||||
|
||||
/* (5.4) Add resource to list (update VueJS) */
|
||||
var newRes = {};
|
||||
newRes[`id${restyp2}`] = rs.created_id;
|
||||
newRes[`idProf`] = prof;
|
||||
newRes[`volume`] = vol;
|
||||
newRes[`formations`] = [];
|
||||
newRes[`add_form`] = '-';
|
||||
newRes[`new_prof`] = prof;
|
||||
|
||||
gstore.get.manage[restyp].push(newRes);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -236,7 +236,7 @@
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
margin-left: -.4em; // emulate no <select>
|
||||
margin-top: -1em; // replace as if not a select
|
||||
margin-top: -1em; // replace as if not a select
|
||||
margin-bottom: -.3em; // fix layout for following elements
|
||||
|
||||
// remove border
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
flex-wrap: nowrap;
|
||||
|
||||
/* (1.1) Element item */
|
||||
& > div:not(.icon){
|
||||
& > div:not(.icon),
|
||||
& > input{
|
||||
flex: 1 1 0;
|
||||
|
||||
// fix
|
||||
|
@ -69,7 +70,6 @@
|
|||
display: inline-block;
|
||||
position: relative;
|
||||
height: 1.8em;
|
||||
width: auto;
|
||||
|
||||
margin: 0;
|
||||
margin-right: 1em;
|
||||
|
@ -91,12 +91,25 @@
|
|||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
justify-self: space-around;
|
||||
flex: 0 1 20em;
|
||||
|
||||
&.min{ flex: 0 1 5em; }
|
||||
|
||||
}
|
||||
|
||||
/* (1.4) Icon (remove) */
|
||||
/* (1.4) Input */
|
||||
& > input{
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
min-width: 0;
|
||||
|
||||
margin: 0;
|
||||
padding: .22em .5em;
|
||||
|
||||
flex: 0 1 5em;
|
||||
}
|
||||
|
||||
/* (1.5) Icon (remove) */
|
||||
& > div.icon{
|
||||
display: inline-block;
|
||||
width: 1.2em;
|
||||
|
@ -104,14 +117,19 @@
|
|||
|
||||
margin-right: 1em;
|
||||
|
||||
background: url('/asset/svg/cross.svg@aaaaaa') center center no-repeat;
|
||||
background: url('/asset/svg/plus.svg@aaaaaa') center center no-repeat;
|
||||
background-size: 60% auto;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&:hover{ background-image: url('/asset/svg/cross.svg@#{$rd-form-invalid-color}'); }
|
||||
&:hover{ background-image: url('/asset/svg/plus.svg@#{$rd-form-valid-color}'); }
|
||||
|
||||
&.remove{
|
||||
background-image: url('/asset/svg/cross.svg@aaaaaa');
|
||||
&:hover{ background-image: url('/asset/svg/cross.svg@#{$rd-form-invalid-color}'); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@
|
|||
|
||||
// force red text
|
||||
&.invalid{ color: $form-invalid-color; }
|
||||
|
||||
&[data-valid='1']{ color: $form-valid-color; }
|
||||
&[data-neutral='1']{ color: $form-neutral-color; }
|
||||
&[data-search='1']{ color: $form-search-color; }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
color: #999;
|
||||
font-size: .8em;
|
||||
white-space: nowrap;
|
||||
|
||||
cursor: default;
|
||||
|
||||
|
|
Loading…
Reference in New Issue