Semaine du 2 au 6 février

Journal de stage : semaine du lundi 2 au vendredi 6 février 2015

Voici mes entrées de journal pour cette quatrième semaine de stage. Cette semaine je continuerais le développement de mon application web et je ferrais une refonte de la base de données.

Lundi 2 février 2015

J’ai commencer ma journée par essayer de revoir mon affichage des mois en français, au final je pense que, même si c’est plus lourd dans le code, il serait préférable de passer par PHP pour traduire manuellement, de cette façon j’éviterais sûrement les problèmes d’encodage, et ce même lors de la mise en place sur le serveur de production.

Au final avec cet technique ça à été plutôt rapide, c’est juste redondant à écrire. J’ai utilisé une structure SWITCH/CASE, je pense que c’est facilement simplifiable mais tant que ça marche, pour le moment …

<?php

foreach ($mois as $row_mois) {
	switch ($row_mois) {
		case '01':
			$mois_lib = "Janvier";
			break;
		case '02':
			$mois_lib = "Février";
			break;
		// etc.
	}
}

?>
Structure plutôt lourde dans le code ...

mois_fr

Une fois tout ceci terminer j’ai voulu commencer le module de commentaire et d’historique, seulement cela demande la refonte de la base de données, et je ferrais cela avec Mme Fichet Mercredi. En attendant j’ai revu mon MCD que j’avais « gribouillé » tableau, je pense qu’il est a peu près correct, j’ai juste quelque interrogation pour la partie « historique » du ticket (je préfère appeler cela « archive »), je me demande quelles données conserver, en ce qui concerne les tables qui possèdent  des données liés au ticket, sans clé étrangère …

WIN_20150202_170458

Enfin je pense qu’une bonne partie du travail est fait, je pense que ça accélérera la réflexion que nous aurons avec Mme Fichet.

j’ai poursuivi la journée en améliorant de façon globale l’application, en ajoutant quelque message d’informations, en améliorant le rendu des formulaires de regroupements …

J’ai commencer à créer un script JavaScript, en utilisant l’API JQuery pour trier les colonnes au clic de l’en-tête de l’une d’elle. C’est plutôt compliqué, j’ai du mal à faire mes sélecteurs pour prendre une colonne (le problème c’est que les tableaux HTML fonctionnent par lignes et non par colonnes) d’autant plus que j’ai à gérer une ligne supplémentaire qui est caché (là où est ma description). Mais j’avance petit à petit.

$('th').click(function() {
	var id_tableau = $(this).parents('table').attr('id');
	var colonne = $('th').index(this);
	var ordre = (toggler ? "ASC" : "DESC");
	trierTableau(id_tableau, colonne, ordre);
	toggler = !toggler;
});
Opérateur ternaire ligne 4 !
/**
 * Tri du contenu d'un tableau en fonction d'une colonne et d'un ordre croissant/décroissant choisi
 * 
 * @param id_tableau string Identifiant DOM du tableau où l'on va effecuter le tri
 * @param colonne int Index de la colonne à trier (0, 1, 2 ...)
 * @param ordre function Ordre de tri, croissant ou décroissant (ordre = ASC || ordre = DESC)
 */
function trierTableau(id_tableau, colonne, ordre) {...}

J’ai réussi à placer un opérateur ternaire, ce n’est pas très impressionnant mais c’est toujours agréable à placer ! Mon script semble correct mais il ne se passe rien, il doit y avoir une petite erreur quelque part.

J’ai également améliorer mon formulaire de création d’un ticket, en y ajoutant un petit peu de javascript, cela à été plutôt rapide puisqu’il n’y a que deux champs « libre » : titre et description, les autres champs ne sont que des listes, donc pas d’erreur possible !

easyform

Pour demain j’essayerais de continuer mon script JavaScript pour trier les tableaux par colonnes, et je poursuivrais l’amélioration de l’ergonomie globale de l’application.


Mardi 3 février 2015

J’ai commencer la journée par améliorer rapidement le formulaire de création du ticket, j’y ai incorporer un message d’information type « snackbar« , la snackbar est originellement native d’Android mais je me suis inspiré de l’idée. C’est une petite fenêtre pop-in d’information non-intrusive dans la navigation de l’utilisateur, elle permet d’afficher un bref message d’information, voir d’intégrer un bouton d’action.

sb

J’ai simplement créer une fonction à appelé, qui affiche la snackbar. De cette façon elle est très modulaire, je peux l’importer dans n’importe quelle page.

<?php

/**
 * Permet d'afficher une snackbar comportand un message
 * @param  string $message Message à placer dans la snackbar
 * @return string Renvoie les éléments HTML permettant d'afficher la snackbar	
 */
function snackBar($message){...}

?>

Je l’ai améliorer en ajoutant une petite ligne de JQuery, elle s’affiche avec un effet de « glisse » vers le haut, puis disparaît avec l’effet inverse au bout de 7 secondes.

sb2

Mme Fichet est passée rapidement, elle a jeté un coup d’œil sur mon MCD gribouillé au tableau, nous avons brièvement rajouté quelque détails, en tout cas il a l’air a peu près correct, je n’avais pas pensé à faire des identifiants relatifs mais dans ce cas je pouvais en faire deux, de toute façon nous verrons cela plus en détail demain.

J’ai poursuivi la journée en commençant à créer la fonctionnalité l’impression, l’idée est de pouvoir, depuis la listes des tickets en cours, sélectionné les tickets que l’on souhaite, puis être redirigé sur une page où l’on pourrait visualiser ces ticket avant impression. L’idéal serait de pouvoir les ré-organisés à souhait avant l’impression.

J’ai tout simplement commencer par créé des cases à cocher (checkbox) dans une colonne supplémentaires dans mes tableaux HTML, et un bouton avec une icône d’imprimante qui fait le lien vers la nouvelle page d’aperçu des tickets avant impression (fiche de ticket). La finalité sera de pouvoir cliquer sur l’en-tête de la colonne « Imprimer » pour cocher toute les checkbox s’y trouvant, l’application devrait normalement conserver l’ordre.

printbitchEn créant la colonnes pour les impression j’ai trouver des erreurs dans mon HTML, j’avais des balises de lignes de tableaux fermante (</tr>) mais pas ouvrante, de ce fait j’ai des erreurs dans mon DOM, ce qui devrait surement expliquer pourquoi je n’arrivais à rien avec mon javascript pour trier mon tableau (dans lequel j’avais justement des sélecteurs sur les balises <tr> …).

J’ai créer une petite media query qui charge une feuille de style spécialement pour le support papier, « print » en anglais (« imprimé » littéralement). Ça se fait très simplement, je n’ai plus eu qu’à cacher les éléments inutiles au support papier, pour l’impression, tel que les en-têtes et pieds de page, les éléments de navigation, certaines images …

<link rel="stylesheet" media="screen" type="text/css" href="/atelier/css/style.css">
<link rel="stylesheet" media="print" type="text/css" href="/atelier/css/print.css">

Chrome peut afficher un aperçu de la page avant impression, ce qui est pratique pour visualiser la mise en forme de la page en version imprimé et pour faire la mise en page de cette page d’impression …

print prev

Ensuite pour imprimer la page, il existe une fonction en javascript pour réaliser ceci, je n’ai eu qu’à créer un bouton qui appel cette fonction au clic de celui-ci.

<button type="button" class="button" onclick="window.print()">
	Imprimer la page
</button>

Cette page est pour moi à peu près terminée, cela manque un petit peu de style mais c’est correct pour le moment. On ne peut pas réorganiser les tickets en l’état actuel.

J’ai passer un peu de temps pour installer un package sur mon éditeur de texte, Sublime Text, il s’agit de LiveReload (où je détaille l’installation sur cet article), cela permet d’afficher en temps réel les modifications faites dans le code sans avoir à constamment recharger la page. J’ai perdu un peu de temps avec ça mais je sens que ça va vraiment augmenté ma vitesse de production. J’utilise désormais un deuxième écran que je branche à mon ordinateur pour afficher seulement l’application, ainsi j’ai d’un coté mon code et de l’autre le rendu en direct de mon code.

Demain je ferrais la refonte de la base de données avec Mme Fichet, de ce fait je devrais réadapter tout mon code en plus du travail qu’il y a a faire sur la base.


 Mercredi 4 février 2015

Nous avons avec Mme Fichet réfléchi sur la nouvelle structure de la base à partir du MCD que j’ai fais au tableau, nous nous sommes demandé s’il était vraiment nécessaire de passer avec un système classique de clef étrangère pour les tables paramètres (catégorie, statut, lieu, etc …), sachant qu’une base de données SQL est quelque chose de vraiment léger. Par exemple la base existante pèse à peine 400 kio avec les données, ce qui est vraiment très peu, en 2015.

Finalement nous avons décidé de conserver cette logique de clef étrangère pour ces petites tables paramètres, en vus d’éventuelles amélioration. Par exemple ajouter les salles des bâtiments dans la table « lieu » ou ajouté une colonne « délai » dans la table importance.

J’avais remarqué que sur l’ancienne base de données, le moteur de stockage était « MyISAM », et après quelque recherche il s’avère que ce moteur ne prend pas en charge les clefs étrangères. Je pense que ce choix n’était pas volontaire puisque l’instruction « FOREIGN KEY » apparaît clairement dans l’ancien script de création des tables.

Enfin, j’ai reproduit le MCD sous Win’Desgin, pour générer un MRD puis le script de création de la base. D’ailleurs si j’avais des problèmes avec Win’Desgin c’est parce que je ne l’avait pas correctement activé, Mme Fichet m’a passé une nouvelle clé, maintenant il fonctionne correctement.

Sous-modèle1

Une fois la base créer j’ai exporter avec phpMyAdmin (PMA) les tables dont le contenu ne changerais pas :

  • importance
  • categorie
  • lieu
  • statut
  • utilisateur

A l’export, PMA fournie tout les valeurs des colonnes, même les clefs primaires, et comme mes clefs primaire sont du type atuo incrémentée, je vais éviter de les re-fournir. J’ai utilisé seulement les clauses INSERT INTO des script d’export de PMA, et les ai adapté pour ma nouvelle base.

-- Avant

INSERT INTO `classe` (`num`, `nom`) VALUES
(1, 'Administrateur'),
(2, 'Agent chef'),
(3, 'Agent'),
(4, 'Inactif');

-- Après

INSERT INTO `classe` (`NOM`) VALUES
('Administrateur'),
('Agent chef'),
('Agent'),
('Inactif');

J’ai également ajouter quelque valeurs dans la nouvelle table « action », puisqu’elle fait partie des tables dont les valeurs resteront fixes (ou du moins qui changeront peu).

Evidemment presque plus rien ne fonctionnait dans mon application, j’ai commencer à réadapter tout le code depuis le début. Il n’y avait presque rien à modifier pour la page de connexion mais en revanche j’ai pu grandement améliorer le fonctionnement de mon formulaire d’ajout de ticket, et faire les choses en propre grâce à ma nouvelle base.

Désormais, seul le titre et  la description du ticket sont obligatoire à la création, tous les autres champs pourront être formuler lors de l’attribution du ticket (pages « Attribuer« ). Ce qui nous donne le tableau de validation suivant :

Champ Condition de validation
Titre Obligatoire, texte court simple
Description Obligatoire, texte long simple
Importance Optionnel (liste)
Catégorie Optionnel (liste)
Lieu Optionnel (liste)
Attribué à un agent Optionnel (liste)
Lieu Optionnel (liste)

Bien sûr si tout les champs du formulaire est rempli correctement, le ticket ira directement dans « En cours » et non « Attribuer« , et on créé une évolution avec l’action « attribuer » pour ce ticket.

Demain je poursuivrais l’adaptation du code sur le reste de l’application.


 Jeudi 5 février 2015

Je continue de réadapter mon code avec la nouvelle base, cette fois ci je me remet sur mes listes, pour afficher les tickets à attribuer, en cours, etc. Il faut que je ré-étudie mon module de tri pour faire mes tableau de regroupement.

J’ai réadapté tout le code pour la nouvelle base, désormais on peut filtrer par agent responsable (puisque les clefs étrangère existe maintenant). Mon script fonctionne correctement maintenant. J’ai profiter du fait que je travailler à nouveau sur cette fonction pour rendre le code un peu plus propre et compréhensible, j’ai commencé à faire un logigramme pour modéliser cette fonction.

<?php

/**
 * Permet de générer des tableaux contenants des tickets selon un critère de regroupement, cette fonction va générer
 * plusieur requête SQL et va renvoyer le résultat dans des tableaux HTML
 * 
 * @param  string $regroup  Critère de regroupement, doit être un nom de colonne de la table SQL `ticket`
 * @param  array  $order_by Tableau contenant les nom de colonnes de la table SQL `ticket` pour trier avec une clause ORDER BY
 * @param  string $ordre    Ordre de tri pour la clause ORDER BY, doit être égal à "ASC" ou "DESC"
 * @param  string $action   Action de la page, si la page où la fonction est appellé est lister_ticket_encours.php, l'action sera "encours", etc
 * @param  PDO    $pdo      Instance de l'objet PDO permettant de dialoguer avec la base de donnée
 * @return string           Renvoie les résultat dans des tableaux HTML 
 */
function grouperTicket($regroup, array $order_by, $ordre, $action, PDO $pdo) {...}

?>

J’ai ensuite créer une fonction pour générer le formulaire de tri, auparavant il était écris brut dans le code HTML, ce qui n’est pas très pratique et peu souple dans le développement.

<?php

/**
 * Créé un formulaire pour que l'utilisateur puisse choisir les paramètres passé dans la fonction grouperTicket()
 * @param  string $action	Action de la page, si la page où la fonction est appellé est lister_ticket_encours.php, l'action sera "encours", etc
 * @param  array $get		Superglobale $_GET pour initialiser le formulaire au chargement de la page suivant le critère choisi
 * @return string			Renvoie le formulaire pour fonctionner avec la fonction grouperTicket()
 */
function getFormulaire($action, $get) {..}

?>

Désormais c’est beaucoup plus modulaire et simple d’utilisation dans les pages de liste, elle sont beaucoup plus légères et ainsi si j’ai des petites corrections à faire je n’aurais qu’à toucher aux fonctions et non à chaque page pour chaque action.

Pour le paramètre « $get » de ma fonction générant le formulaire, j’ai utilisé une équation ternaire, c’est un peu compliqué à lire mais j’aime beaucoup les utilisés. Avec ceci je peux donner un paramètre par défaut pour ma fonction dans le cas où la variable $_GET n’est pas initialisée.

$get['regroup'] = isset($_GET['regroup']) ? $_GET['regroup'] : 'd_ouverture';
echo getFormulaire($action, $get);

D’ailleurs, je ne sais même pas si ce paramètre à lieu d’être, il me semble que les superglobale de PHP sont accessible n’importe où dans le code sans qu’aucune action particulière doit être faite. Enfin je ne pense pas non plus que ça alourdisse énormément le code alors je vais laisser cela ainsi.

Au final j’ai quelque éléments plutôt redondant dans mon code, qui revienne sur chaque page, je pense les mettre dans des fonctions qu’il n’y aurait plus qu’à appeler avec PHP, je pense que c’est une bonne approche.

Demain je poursuivrai mon développement dans la même direction, je pense également qu’il faudra explorer la piste d’un nouveaux cas d’utilisation, « gérer les actions », ou quelque chose dans le genre. Pour que l’administrateur puisse gérer les actions.


 Vendredi 6 février 2015

J’ai commencé ma journée par corriger quelque bug sur les adaptions que j’ai faite hier, puis j’ai placé mes éléments modulaires dans chaque page de liste. Maintenant les listes sont totalement fonctionnelle. Je pense qu’il faudra voir avec l’équipe de l’atelier quelle colonnes afficher sur les listes car pour l’instant il y en a trop, les cases du tableau sont disproportionné et dépasse en largeur.

troplargelol

Comme je n’ai plus de données dans ma base, j’ai remarqué que je ne gérais pas le cas où il n’y avait aucun résultats à afficher, c’est tout bête mais cela fait partie des choses auxquelles il faut penser. Je créé des tickets avec chacun un paramètre différents de définit grâce à mon formulaire d’ajout, ainsi je vérifie que tout fonctionne correctement et je me créer un jeu de test propre pour la nouvelle base.

Je pourrais m’embêter à ré-importer les anciens tickets mais le problème c’est de savoir s’ils ont été tous correctement remplis, ce dont je ne suis pas sûr.

J’ai débuter le développement du module « commentaire » et « évolution ». Pour ces deux modules je vais utiliser le même  principe que pour le reste, je créé des fonctions qui prenne en paramètre un l’identifiant d’un ticket, et qui renvoie en retour toute les informations relatives à ce tickets pour les commentaires ou les évolutions, organisées visuellement évidement.

J’ai commencé brièvement sur les commentaires, pour le moment le module informe seulement si il y a des commentaires ou non, je voulais me prioriser sur le module évolution pour que je continue de tester mon application avec mon jeu de test, s’il fonctionne correctement je verrais les informations s’afficher au fur et à mesure de la vie du ticket.

<?php

/**
 * Renvoie les informations sur un ticket passé en paramètre relatives à l'évolution de celui-ci
 * @param  int $id_ticket	Identifiant de la talbe SQL `ticket`
 * @param  PDO $pdo			Instance de l'objet PDO permettant de dialoguer avec la base de donnée
 * @return string			Renvoie sur forme d'élément HTML les évolutions du ticket
 */
function getEvolution($id_ticket, $pdo) {...}

?>

Pour l’instant le module évolution ne m’affiche que le créateur du ticket, en effet le traitement est différent pour cette donnée puisque qu’elle est stockée dans la table « ticket » et non la table « évolution« . En revanche pour tout le reste des données provenant de cette dernière, le traitement sera le même.histoalpha

Dans la même démarche d’optimisation des éléments redondant, je pense que je pourrais créer une fonction me générant les pages de détails, avec une fonction je pourrais donner en paramètre l’action que la page est supposé faire, et donc générer les éléments modifiable ou non. Encore mieux, je pourrais ajouter un paramètre (un booléen par exemple) pour indiquer si l’utilisateur veut modifier ou non le ticket, et ainsi rendre tout les champs modifiables.

Je pense que créer une telle fonction va être compliqué mais à mon avis c’est une très bonne façon de faire.

Après avoir réfléchi un peu plus sur le problème, je pense créer plusieurs petite fonction qui vont générer mes champs, en fonction de leurs types (lecture seule, texte, listes …) qui seront appelé dans une autre fonction pour générer la fiche de détail en mode édition, ou selon l’action attendu par la page de détail (résoudre, attribuer …).

La semaine prochaine je poursuivrai l’adaptation des autres pages de détails, avec leurs module de commentaire et d’évolution , après cela l’application sera complète pour cette partie.

⇐ Page de journal pour la semaine précédente 

Page de journal pour la semaine suivante ⇒

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *