From ba30174b025e1748abfeb54c5e1a75c26c89bb21 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Wed, 7 Mar 2018 12:12:50 +0100 Subject: [PATCH 1/9] [webpack.teacher.view] added 'remove' and 'edit' icons (to implement) --- webpack/component/teacher/view.vue | 3 ++ webpack/scss/constants.scss | 10 ++-- webpack/scss/container.scss | 75 +++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 26 deletions(-) diff --git a/webpack/component/teacher/view.vue b/webpack/component/teacher/view.vue index 090fe66..e72a2e9 100644 --- a/webpack/component/teacher/view.vue +++ b/webpack/component/teacher/view.vue @@ -38,6 +38,9 @@ :data-lname='prof.lastName' :data-fname='prof.firstName'> +
+
+ {{ prof.categorie }}

{{ prof.firstName }} {{ prof.lastName }}

diff --git a/webpack/scss/constants.scss b/webpack/scss/constants.scss index 7525ff5..089657b 100644 --- a/webpack/scss/constants.scss +++ b/webpack/scss/constants.scss @@ -10,7 +10,7 @@ $error-color: #cc5857; /* FORMULAIRES */ $form-valid-color: #20d696; $form-neutral-color: #b8c0c8; -$form-search-color: #e5c41d; +$form-search-color: #1d74e5; $form-invalid-color: #ea4b35; $form-grey-color: lighten($secondary-color, 5%); @@ -19,10 +19,10 @@ $form-grey-color: lighten($secondary-color, 5%); // POUR RESOURCE_DISPATCHER -$rd-form-valid-color: '27a560'; -$rd-form-neutral-color: '2193e6'; -$rd-form-search-color: '5630ed'; -$rd-form-invalid-color: 'd52918'; +$rd-form-valid-color: '20d696'; +$rd-form-neutral-color: 'b8c0c8'; +$rd-form-search-color: '1d74e5'; +$rd-form-invalid-color: 'ea4b35'; // Menu $menu-bg: #fff; diff --git a/webpack/scss/container.scss b/webpack/scss/container.scss index 4c52063..02a6d0f 100644 --- a/webpack/scss/container.scss +++ b/webpack/scss/container.scss @@ -163,12 +163,48 @@ &.search-hidden, &.filter-hidden{ display: none; } - /* (2) Card generic title */ + + /* (2) REMOVE+EDIT button */ + & > div.remove[data-remove], + & > div.edit[data-edit]{ + display: inline-block; + position: absolute; + top: 1.3em; + left: calc( 100% - 2em ); + width: 1em; + height: 1em; + + background: url('/asset/svg/remove.svg@bbbbbb') center center no-repeat; + background-size: auto 100%; + + cursor: pointer; + + &:hover{ + background-image: url('/asset/svg/remove.svg@#{$rd-form-invalid-color}'); + } + + } + + /* (3) EDIT button */ + & > div.edit[data-edit]{ + left: calc( 100% - 2em - 1.3em ); + + background-image: url('/asset/svg/td.svg@bbbbbb'); + background-size: 80% auto; + + &:hover{ + background-image: url('/asset/svg/td.svg@#{$rd-form-search-color}'); + } + + } + + /* (4) Card generic title */ & > span.category, & > select.category{ display: block; position: relative; + width: calc( 100% - 3em ); margin-bottom: .5em; @@ -179,7 +215,7 @@ } - /* (2-edot) Card generic title (select) */ + /* (4-edit) Card generic title (select) */ & > select.category{ margin: 0; @@ -202,7 +238,7 @@ } - /* (3) Card title */ + /* (5) Card title */ & > h1{ display: flex; @@ -232,7 +268,7 @@ text-anchor: center; } - /* (3-edit) Card title -> edit inputs */ + /* (5-edit) Card title -> edit inputs */ input{ display: inline-block; @@ -257,7 +293,7 @@ } - /* (4) Card 2-column array */ + /* (6) Card 2-column array */ & > div.table{ display: flex; @@ -275,7 +311,7 @@ align-items: center; flex-wrap: nowrap; - /* (5) Column */ + /* (6.1) Column */ & > div{ display: flex; @@ -296,7 +332,7 @@ align-items: center; flex-wrap: nowrap; - /* (5.1) Column Emphasis */ + /* (6.1.1) Column Emphasis */ & > span, & > span:first-child{ display: block; @@ -307,7 +343,7 @@ font-size: 1.5em; letter-spacing: .05em; - /* (5.1-edit) Editable text entry */ + /* (6.1.1-edit) Editable text entry */ & > input{ display: inline-block; width: 2em; @@ -323,7 +359,7 @@ } } - /* (5.2) Column Emphasis */ + /* (6.2) Column Emphasis */ & > span:last-child{ display: block; position: relative; @@ -343,7 +379,7 @@ } - /* (6) Card footer */ + /* (7) Card footer */ & > div.footer{ display: flex; @@ -370,7 +406,7 @@ flex-wrap: nowrap; - /* (6.1) Card footer element */ + /* (7.1) Card footer element */ & > span{ display: flex; @@ -422,7 +458,12 @@ } - /* (6.2) Card footer separator */ + /* (7.1-edit) Card button submit */ + & > button{ + margin: auto; + } + + /* (7.2) Card footer separator */ & > hr{ display: block; position: relative; @@ -432,17 +473,9 @@ border: 0; background-color: darken(#fff, 10%); } - - /* (6-edit) Card button submit */ - & > button{ - margin: auto; - } - } - - - /* (6) Card sub */ + /* (8) Card sub */ & > div.sub{ display: inline-block; From f491d9736d0c8abfe6e4dc9649cc768263320890 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Wed, 7 Mar 2018 12:25:57 +0100 Subject: [PATCH 2/9] minfix css for pop-up --- webpack/scss/pop-up.scss | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/webpack/scss/pop-up.scss b/webpack/scss/pop-up.scss index 47c963e..8ae6691 100644 --- a/webpack/scss/pop-up.scss +++ b/webpack/scss/pop-up.scss @@ -19,9 +19,7 @@ border-radius: 5px; background: $bg-color; - color: $secondary-color; - - box-shadow: -10px 10px 0 rgba(26, 33, 40, .8); + color: $primary-color; -webkit-transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%); @@ -56,9 +54,8 @@ padding: 1em; - b, strong{ - color: $primary-color; - } + b, strong{ color: darken($primary-color, 10%); } + } & > .footer{ From c3c59737d1bcf07e7c2857e0c19248d4db90679e Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Wed, 7 Mar 2018 13:13:31 +0100 Subject: [PATCH 3/9] [webpack.teacher.view]] Can now REMOVE (delete) professors --- webpack/component/teacher/view.vue | 6 +-- webpack/data/teacher.js | 83 ++++++++++++++++++++++++++++++ webpack/scss/container.scss | 4 ++ webpack/scss/pop-up.scss | 12 ++--- 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/webpack/component/teacher/view.vue b/webpack/component/teacher/view.vue index e72a2e9..d5decff 100644 --- a/webpack/component/teacher/view.vue +++ b/webpack/component/teacher/view.vue @@ -6,7 +6,7 @@
-
+

- +

- + heures à faire
diff --git a/webpack/data/teacher.js b/webpack/data/teacher.js index 68786ee..3f1b965 100644 --- a/webpack/data/teacher.js +++ b/webpack/data/teacher.js @@ -216,15 +216,7 @@ gstore.add('ir_handler', function(prof_id){ if( prof_id == null || isNaN(prof_id) ) return; - /* (2) Prepare confirmation pop-up */ - var popup_rq = { - title: 'Confirmation de suppression', - content: "La suppression de l'enseignant sadkfjsdlkf est irréversible.

Voulez-vous le supprimer définitivement ?", - action: 'Supprimer', - type: 'invalid' - }; - - /* (3) Show popup */ + /* (2) Show popup */ (new Promise( (resolve, reject) => { popup.ask({ @@ -239,39 +231,39 @@ gstore.add('ir_handler', function(prof_id){ return new Promise( (resolve, reject) => { - /* (3.1) Delete professor */ + /* (2.1) Delete professor */ api.call('DELETE professor/'+prof_id, {}, function(rs){ - /* (3.1.1) Abort on error */ + /* (2.1.1) Abort on error */ if( rs.error !== 0 || rs.deleted !== true ) return reject(rs.error); - /* (3.1.2) Success */ + /* (2.1.2) Success */ resolve(); }); }); - /* (4) On success */ + /* (3) On success */ }).then(function(){ - /* (4.1) Find index in gstore */ + /* (3.1) Find index in gstore */ var gi = gstore.get.professors.map( (data, i) => { return ( data.idProfesseur && data.idProfesseur == prof_id ) ? i : ''; }).join(''); - /* (4.2) Do nothing if not found */ + /* (3.2) Do nothing if not found */ if( isNaN(gi) ) return; - /* (4.3) Else -> remove from visible */ + /* (3.3) Else -> remove from visible */ gstore.get.professors.splice(gi, 1); - /* (5) On error */ + /* (4) On error */ }).catch(function(err_code){ popup.ask({ title: 'Error ('+err_code+')', - content: 'La suppression à échoué. Veuillez réessayer ultérieurement.', + content: 'La suppression a échouée. Veuillez réessayer ultérieurement.', action: 'OK', type: 'neutral' }, () => {}); @@ -279,11 +271,75 @@ gstore.add('ir_handler', function(prof_id){ }); - - - - - }); + + + +/* (6) Manage instant edit +---------------------------------------------------------*/ +/* (1) Define edit handler */ +gstore.add('ie_handler', function(prof_id){ + + /* (1) Abort if wrong prof_id */ + if( prof_id == null || isNaN(prof_id) ) + return; + + /* (2) Show popup */ + (new Promise( (resolve, reject) => { + + popup.ask({ + title: 'Confirmation de modification', + content: "La modification de l'enseignant sadkfjsdlkf est irréversible.

Voulez-vous le modifier ?", + action: 'Modifier', + type: 'search' + }, (popup_rs) => { popup_rs && resolve() }); + + })).then(function(){ + + + return new Promise( (resolve, reject) => { + + /* (2.1) Delete professor */ + api.call('PUT professor/'+prof_id, {}, function(rs){ + + /* (2.1.1) Abort on error */ + if( rs.error !== 0 || rs.updated !== true ) + return reject(rs.error); + + /* (2.1.2) Success */ + resolve(); + + }); + + }); + + /* (3) On success */ + }).then(function(){ + + /* (3.1) Find index in gstore */ + var gi = gstore.get.professors.map( (data, i) => { return ( data.idProfesseur && data.idProfesseur == prof_id ) ? i : ''; }).join(''); + + /* (3.2) Do nothing if not found */ + if( isNaN(gi) ) return; + + /* (3.3) Else -> update VueJS element */ + // gstore.get.professors[gi]; + + + + /* (4) 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' + }, () => {}); + + }); + + +}); \ No newline at end of file From 0b5272c8ec44c17d80b270850cb1828c1cfbfe1e Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Wed, 7 Mar 2018 14:34:18 +0100 Subject: [PATCH 5/9] [config.modules] make POST professor types more flexible --- config/modules.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/modules.json b/config/modules.json index f6b6e74..c290f4e 100644 --- a/config/modules.json +++ b/config/modules.json @@ -92,9 +92,9 @@ "lastName": { "des": "Professor first name.", "typ": "varchar(2,30,alphanumeric)" }, "category": { "des": "Professor category UID.", "typ": "id" }, "hoursToDo": { "des": "Number of hours professor have to do", "typ": "id" }, - "initials": { "des": "Professor initials", "typ": "varchar(2,2,letters)" }, + "initials": { "des": "Professor initials", "typ": "varchar(2,8,letters)" }, "isAdmin": { "des": "Whether professor is an admin", "typ": "boolean" }, - "casLogin": { "des": "Optional CAS username", "typ": "varchar(6,10,letters)", "opt": true } + "casLogin": { "des": "Optional CAS username", "typ": "varchar(6,16,letters)", "opt": true } }, "out": { "created_uid": { "des": "Created professor UID", "typ": "id" } From e81888697237d0a73095f14ac4d35b9ab0ddc991 Mon Sep 17 00:00:00 2001 From: xdrm-brackets Date: Wed, 7 Mar 2018 14:34:44 +0100 Subject: [PATCH 6/9] [webpack.teacher.view] can now CREATE professors --- public_html/asset/svg/admin.svg | 45 ++++++++++++ webpack/component/teacher/view.vue | 20 +++--- webpack/data/teacher.js | 106 ++++++++++++++++++++++++++++- webpack/scss/container.scss | 74 ++++++++++++++++++-- 4 files changed, 229 insertions(+), 16 deletions(-) create mode 100644 public_html/asset/svg/admin.svg diff --git a/public_html/asset/svg/admin.svg b/public_html/asset/svg/admin.svg new file mode 100644 index 0000000..2a37dbc --- /dev/null +++ b/public_html/asset/svg/admin.svg @@ -0,0 +1,45 @@ + +image/svg+xml \ No newline at end of file diff --git a/webpack/component/teacher/view.vue b/webpack/component/teacher/view.vue index 6fb1bfc..ffcf0be 100644 --- a/webpack/component/teacher/view.vue +++ b/webpack/component/teacher/view.vue @@ -8,25 +8,26 @@
- +

- + +

- + heures à faire
-
 
+
{{ gstore.create_err }}
@@ -38,11 +39,12 @@ :data-lname='prof.lastName' :data-fname='prof.firstName'> -
-
+
+
+
{{ prof.categorie }} -

{{ prof.firstName }} {{ prof.lastName }}

+

{{ prof.firstName }} {{ prof.lastName }} {{ prof.casLogin }}

diff --git a/webpack/data/teacher.js b/webpack/data/teacher.js index 3f1b965..9c496d5 100644 --- a/webpack/data/teacher.js +++ b/webpack/data/teacher.js @@ -207,7 +207,109 @@ gstore.add('is_handler', function(e){ -/* (5) Manage instant remove +/* (5) Manage instant create +---------------------------------------------------------*/ +/* (1) Initialize inputs */ +gstore.add('create_cat', '-'); +gstore.add('create_name', ''); +gstore.add('create_cas', ''); +gstore.add('create_h', ''); + +/* (2) Initialize error message */ +gstore.add('create_err', ''); + +/* (3) Define create handler */ +gstore.add('ic_handler', function(prof_id){ + + /* (3.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(); + + /* (3.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; + + console.log(cat, name, cas, hour); + + /* (3.3) Init client-side check */ + var errors = []; + + /* (3.3.1) Check category */ + if( isNaN(cat) ) errors.push('La catégorie de l\'enseignant est manquante'); + + /* (3.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"'); + + /* (3.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'); + + /* (3.3.4) Check hours */ + if( hour === '' || isNaN(hour) || hour < 0 ) + errors.push('Le nombre d\'heures doit être un entier positif.'); + + /* (3.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.1) Création de la requête */ + var rq = { + firstName: name[1], + lastName: name[0], + category: cat, + initials: name[1].substr(0,2)+name[0].substr(0,2), + hoursToDo: hour, + isAdmin: false + }; + + // optional cas_login + if( cas.length > 0 ) rq.casLogin = cas; + + + /* (4.2) Send request */ + api.call('POST professor', rq, function(rs){ + + console.log(rs); + + /* (4.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.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.2.3) Show that user is created */ + console.log('Create') + + + }); + + + + +}); + + + + + +/* (6) Manage instant remove ---------------------------------------------------------*/ /* (1) Define remove handler */ gstore.add('ir_handler', function(prof_id){ @@ -277,7 +379,7 @@ gstore.add('ir_handler', function(prof_id){ -/* (6) Manage instant edit +/* (7) Manage instant edit ---------------------------------------------------------*/ /* (1) Define edit handler */ gstore.add('ie_handler', function(prof_id){ diff --git a/webpack/scss/container.scss b/webpack/scss/container.scss index 13e0c08..420198a 100644 --- a/webpack/scss/container.scss +++ b/webpack/scss/container.scss @@ -168,9 +168,10 @@ &.filter-hidden{ display: none; } - /* (2) REMOVE+EDIT button */ + /* (2) REMOVE+EDIT+ADMIN button */ & > div.remove[data-remove], - & > div.edit[data-edit]{ + & > div.edit[data-edit], + & > div.admin[data-admin]{ display: inline-block; position: absolute; top: 1.3em; @@ -189,7 +190,7 @@ } - /* (3) EDIT button */ + /* (2.1) EDIT button */ & > div.edit[data-edit]{ left: calc( 100% - 2em - 1.3em ); @@ -202,13 +203,26 @@ } + /* (2.2) ADMIN switch */ + & > div.admin[data-admin]{ + left: calc( 100% - 2em - 1.3em - 1.3em ); + + background-image: url('/asset/svg/admin.svg@bbbbbb'); + background-size: 85% auto; + + &:hover{ background-image: url('/asset/svg/admin.svg@bbbbbb'); } + + &[data-active='1']{ background-image: url('/asset/svg/admin.svg@f4bd18'); } + + } + /* (4) Card generic title */ & > span.category, & > select.category{ display: block; position: relative; - width: calc( 100% - 3em ); + width: calc( 100% - 5em ); margin-bottom: .5em; @@ -222,6 +236,7 @@ /* (4-edit) Card generic title (select) */ & > select.category{ + width: calc( 100% + 1em ); margin: 0; padding: 0; margin-left: -.4em; // emulate no