| 3392 | delphine | 1 | function WidgetApa() {
 | 
        
           |  |  | 2 | 	this.utils = new UtilsApa();
 | 
        
           |  |  | 3 | 	this.mode = null;
 | 
        
           |  |  | 4 | 	this.urlRacine = window.location.origin;
 | 
        
           |  |  | 5 | 	this.urlBaseAuth = null;
 | 
        
           |  |  | 6 | 	this.idUtilisateur = null;
 | 
        
           |  |  | 7 | 	this.infosUtilisateur = null;
 | 
        
           |  |  | 8 | }
 | 
        
           |  |  | 9 |   | 
        
           |  |  | 10 | WidgetApa.prototype.init = function() {
 | 
        
           |  |  | 11 | 	const lthis = this;
 | 
        
           |  |  | 12 |   | 
        
           |  |  | 13 | 	this.urlBaseAuth = this.urlRacine + '/service:annuaire:auth';
 | 
        
           |  |  | 14 | 	$( '#mdp' ).val('');
 | 
        
           |  |  | 15 | 	$( '#inscription' ).attr( 'href',  this.urlSiteTb() + 'inscription' );
 | 
        
           |  |  | 16 | 	$( '#inscription' ).attr( 'href',  this.urlSiteTb() + 'wp-login.php?action=lostpassword' );
 | 
        
           |  |  | 17 |   | 
        
           |  |  | 18 | 	this.chargerStatutSSO();
 | 
        
           |  |  | 19 | 	this.connexionDprodownMenu()
 | 
        
           |  |  | 20 | 	$( '#deconnexion a' ).click( function( event ) {
 | 
        
           |  |  | 21 | 		event.preventDefault();
 | 
        
           |  |  | 22 | 		lthis.deconnecterUtilisateur();
 | 
        
           |  |  | 23 | 	});
 | 
        
           |  |  | 24 |   | 
        
           |  |  | 25 | 	$( '#formulaire' ).on( 'click', '.saisir-plantes,.saisir-lichens', function() {
 | 
        
           |  |  | 26 | 		var nomSquelette = $( this ).data( 'load' );
 | 
        
           |  |  | 27 | 		$( '#charger-form' ).data( 'load', nomSquelette );
 | 
        
           |  |  | 28 | 		lthis.utils.chargerForm( nomSquelette, lthis );
 | 
        
           |  |  | 29 | 		$( '#bouton-list-releves' ).removeClass( 'hidden' );
 | 
        
           |  |  | 30 | 		$( '#table-releves' ).addClass( 'hidden' );
 | 
        
           |  |  | 31 | 	});
 | 
        
           |  |  | 32 | };
 | 
        
           |  |  | 33 |   | 
        
           |  |  | 34 |   | 
        
           |  |  | 35 | /**
 | 
        
           |  |  | 36 |  * Interroge le SSO pour connaître le statut de l'utilisateur, et change le menu
 | 
        
           |  |  | 37 |  * à droite de la barre en fonction
 | 
        
           |  |  | 38 |  */
 | 
        
           |  |  | 39 | WidgetApa.prototype.chargerStatutSSO = function() {
 | 
        
           |  |  | 40 | 	const lthis = this;
 | 
        
           |  |  | 41 | 	var urlAuth = this.urlBaseAuth + '/identite';
 | 
        
           |  |  | 42 |   | 
        
           |  |  | 43 | 	if( 'local' !== this.mode ) {
 | 
        
           |  |  | 44 | 		this.connexion( urlAuth, true );
 | 
        
           |  |  | 45 | 		$( '#connexion' ).click( function( event ) {
 | 
        
           |  |  | 46 | 			event.preventDefault();
 | 
        
           |  |  | 47 | 			if( $( '#utilisateur-connecte' ).hasClass( 'hidden' ) || !lthis.utils.valOk( $( '#nom-complet' ).text() ) ) {
 | 
        
           |  |  | 48 | 				var login = $( '#courriel' ).val(),
 | 
        
           |  |  | 49 | 					mdp   = $( '#mdp' ).val();
 | 
        
           |  |  | 50 | 				if ( lthis.utils.valOk( login ) && lthis.utils.valOk( mdp ) ) {
 | 
        
           |  |  | 51 | 					urlAuth = lthis.urlBaseAuth + '/connexion?login=' + login + '&password=' + mdp;
 | 
        
           |  |  | 52 | 					lthis.connexion( urlAuth, true );
 | 
        
           |  |  | 53 | 				} else {
 | 
        
           |  |  | 54 | 					alert( lthis.utils.msgTraduction( 'non-connexion' ) );
 | 
        
           |  |  | 55 | 				}
 | 
        
           |  |  | 56 | 			}
 | 
        
           |  |  | 57 | 		});
 | 
        
           |  |  | 58 | 	} else {
 | 
        
           |  |  | 59 | 		urlAuth = this.urlRacine + '/widget:cel:modules/apa/test-token.json';
 | 
        
           |  |  | 60 | 		// $( '#connexion' ).click( function( event ) {
 | 
        
           |  |  | 61 | 		// 	event.preventDefault();
 | 
        
           |  |  | 62 | 			// lthis.connexion( urlAuth, true );
 | 
        
           |  |  | 63 | 			this.connexion( urlAuth, true );
 | 
        
           |  |  | 64 | 		// });
 | 
        
           |  |  | 65 | 	}
 | 
        
           |  |  | 66 | };
 | 
        
           |  |  | 67 |   | 
        
           |  |  | 68 | /**
 | 
        
           |  |  | 69 |  * Déconnecte l'utilisateur du SSO
 | 
        
           |  |  | 70 |  */
 | 
        
           |  |  | 71 | WidgetApa.prototype.deconnecterUtilisateur = function() {
 | 
        
           |  |  | 72 | 	var urlAuth = this.urlBaseAuth + '/deconnexion';
 | 
        
           |  |  | 73 |   | 
        
           |  |  | 74 | 	if( 'local' === this.mode ) {
 | 
        
           |  |  | 75 | 		this.definirUtilisateur();
 | 
        
           |  |  | 76 | 		window.location.reload();
 | 
        
           |  |  | 77 | 		return;
 | 
        
           |  |  | 78 | 	}
 | 
        
           |  |  | 79 | 	this.connexion( urlAuth, false );
 | 
        
           |  |  | 80 | };
 | 
        
           |  |  | 81 |   | 
        
           |  |  | 82 | WidgetApa.prototype.connexion = function( urlAuth, connexionOnOff ) {
 | 
        
           |  |  | 83 | 	const lthis = this;
 | 
        
           |  |  | 84 |   | 
        
           |  |  | 85 | 	$.ajax({
 | 
        
           |  |  | 86 | 		url: urlAuth,
 | 
        
           |  |  | 87 | 		type: "GET",
 | 
        
           |  |  | 88 | 		dataType: 'json',
 | 
        
           |  |  | 89 | 		xhrFields: {
 | 
        
           |  |  | 90 | 			withCredentials: true
 | 
        
           |  |  | 91 | 		}
 | 
        
           |  |  | 92 | 	})
 | 
        
           |  |  | 93 | 	.done( function( data ) {
 | 
        
           |  |  | 94 | 		if( connexionOnOff ) {
 | 
        
           |  |  | 95 | 			// connecté
 | 
        
           |  |  | 96 | 			lthis.definirUtilisateur( data.token );
 | 
        
           |  |  | 97 | 		} else {
 | 
        
           |  |  | 98 | 			lthis.definirUtilisateur();
 | 
        
           |  |  | 99 | 			window.location.reload();
 | 
        
           |  |  | 100 | 		}
 | 
        
           |  |  | 101 | 	})
 | 
        
           |  |  | 102 | 	.fail( function( error ) {
 | 
        
           |  |  | 103 | 		// @TODO gérer l'affichage de l'erreur, mais pas facile à placer
 | 
        
           |  |  | 104 | 		// dans l'interface actuelle sans que ce soit moche
 | 
        
           |  |  | 105 | 		//afficherErreurServeur();
 | 
        
           |  |  | 106 | 	});
 | 
        
           |  |  | 107 | };
 | 
        
           |  |  | 108 |   | 
        
           |  |  | 109 |   | 
        
           |  |  | 110 | WidgetApa.prototype.definirUtilisateur = function( jeton ) {
 | 
        
           |  |  | 111 | 	const thisObj = this;
 | 
        
           |  |  | 112 | 	var nomComplet    = '',
 | 
        
           |  |  | 113 | 		courriel      = '',
 | 
        
           |  |  | 114 | 		pseudo        = '',
 | 
        
           |  |  | 115 | 		prenom        = '',
 | 
        
           |  |  | 116 | 		nom           = '';
 | 
        
           |  |  | 117 |   | 
        
           |  |  | 118 | 	// affichage
 | 
        
           |  |  | 119 | 	if ( undefined !== jeton ) {
 | 
        
           |  |  | 120 | 		// décodage jeton
 | 
        
           |  |  | 121 | 		this.infosUtilisateur = this.decoderJeton( jeton );
 | 
        
           |  |  | 122 | 		// console.log(jetonDecode);
 | 
        
           |  |  | 123 |   | 
        
           |  |  | 124 | 		idUtilisateur = this.infosUtilisateur.id;
 | 
        
           |  |  | 125 | 		nomComplet    = this.infosUtilisateur.intitule;
 | 
        
           |  |  | 126 | 		courriel      = this.infosUtilisateur.sub;
 | 
        
           |  |  | 127 | 		pseudo        = this.infosUtilisateur.pseudo;
 | 
        
           |  |  | 128 | 		prenom        = this.infosUtilisateur.prenom;
 | 
        
           |  |  | 129 | 		nom           = this.infosUtilisateur.nom;
 | 
        
           |  |  | 130 | 		$( '#courriel' ).attr( 'disabled', 'disabled' );
 | 
        
           |  |  | 131 | 		$( '#bloc-connexion' ).addClass( 'hidden' );
 | 
        
           |  |  | 132 | 		$( '#utilisateur-connecte, #anonyme' ).removeClass( 'hidden' );
 | 
        
           |  |  | 133 | 	}
 | 
        
           |  |  | 134 | 	$( '#id_utilisateur' ).val( idUtilisateur );
 | 
        
           |  |  | 135 | 	$( '#prenom' ).val( prenom );
 | 
        
           |  |  | 136 | 	$( '#nom' ).val( nom );
 | 
        
           |  |  | 137 | 	$( '#nom-complet' ).html( nomComplet );
 | 
        
           |  |  | 138 | 	$( '#courriel' ).val( courriel );
 | 
        
           |  |  | 139 | 	$( '#profil-utilisateur a' ).attr( 'href', this.urlSiteTb() + 'membres/' + pseudo.toLowerCase().replace( ' ', '-' ) );
 | 
        
           |  |  | 140 | 	if ( this.utils.valOk( idUtilisateur ) ) {
 | 
        
           |  |  | 141 | 		var nomSquelette = $( '#charger-form' ).data( 'load' ) || 'arbres';
 | 
        
           |  |  | 142 | 		this.utils.chargerForm( nomSquelette, thisObj );
 | 
        
           |  |  | 143 | 	}
 | 
        
           |  |  | 144 | };
 | 
        
           |  |  | 145 |   | 
        
           |  |  | 146 | /**
 | 
        
           |  |  | 147 |  * Décodage à l'arrache d'un jeton JWT, ATTENTION CONSIDERE QUE LE
 | 
        
           |  |  | 148 |  * JETON EST VALIDE, ne pas décoder n'importe quoi - pas trouvé de lib simple
 | 
        
           |  |  | 149 |  */
 | 
        
           |  |  | 150 | WidgetApa.prototype.decoderJeton = function( jeton ) {
 | 
        
           |  |  | 151 | 	var parts = jeton.split( '.' ),
 | 
        
           |  |  | 152 | 		payload = parts[1];
 | 
        
           |  |  | 153 | 	payload = this.b64d( payload );
 | 
        
           |  |  | 154 | 	payload = JSON.parse( payload, true );
 | 
        
           |  |  | 155 | 	return payload;
 | 
        
           |  |  | 156 | };
 | 
        
           |  |  | 157 |   | 
        
           |  |  | 158 | /**
 | 
        
           |  |  | 159 |  * Décodage "url-safe" des chaînes base64 retournées par le SSO (lib jwt)
 | 
        
           |  |  | 160 |  */
 | 
        
           |  |  | 161 | WidgetApa.prototype.b64d = function( input ) {
 | 
        
           |  |  | 162 |   var remainder = input.length % 4;
 | 
        
           |  |  | 163 |   | 
        
           |  |  | 164 |   if ( 0 !== remainder ) {
 | 
        
           |  |  | 165 | 	var padlen = 4 - remainder;
 | 
        
           |  |  | 166 |   | 
        
           |  |  | 167 | 	for ( var i = 0; i < padlen; i++ ) {
 | 
        
           |  |  | 168 | 	  input += '=';
 | 
        
           |  |  | 169 | 	}
 | 
        
           |  |  | 170 |   }
 | 
        
           |  |  | 171 |   input = input.replace( '-', '+' );
 | 
        
           |  |  | 172 |   input = input.replace( '_', '/' );
 | 
        
           |  |  | 173 |   return atob( input );
 | 
        
           |  |  | 174 | };
 | 
        
           |  |  | 175 |   | 
        
           |  |  | 176 | WidgetApa.prototype.urlSiteTb = function() {
 | 
        
           |  |  | 177 | 	var urlPart = ( 'test' === this.mode ) ? '/test/' : '/';
 | 
        
           |  |  | 178 |   | 
        
           |  |  | 179 | 	return this.urlRacine + urlPart;
 | 
        
           |  |  | 180 | };
 | 
        
           |  |  | 181 |   | 
        
           |  |  | 182 | // Volet de profil/déconnexion
 | 
        
           |  |  | 183 | WidgetApa.prototype.connexionDprodownMenu = function() {
 | 
        
           |  |  | 184 |   $( '#utilisateur-connecte .volet-toggle, #profil-utilisateur a, #deconnexion a' ).click( function( event ) {
 | 
        
           |  |  | 185 |     if( $( this ).hasClass( 'volet-toggle' ) ) {
 | 
        
           |  |  | 186 |       event.preventDefault();
 | 
        
           |  |  | 187 |     }
 | 
        
           |  |  | 188 |     $( '#utilisateur-connecte .volet-menu' ).toggleClass( 'hidden' );
 | 
        
           |  |  | 189 |   });
 | 
        
           |  |  | 190 | }
 | 
        
           |  |  | 191 |   | 
        
           |  |  | 192 | // Préchargement des infos-obs ************************************************/
 | 
        
           |  |  | 193 |   | 
        
           |  |  | 194 | /**
 | 
        
           |  |  | 195 |  * Callback dans le chargement du formulaire dans #charger-form
 | 
        
           |  |  | 196 |  */
 | 
        
           |  |  | 197 | WidgetApa.prototype.chargerSquelette = function( squelette , nomSquelette ) {
 | 
        
           |  |  | 198 | 	//  à compléter plus tard si nécessaire, pour le moment on charge "arbres"
 | 
        
           |  |  | 199 | 	switch( nomSquelette ) {
 | 
        
           |  |  | 200 | 		case 'plantes' :
 | 
        
           |  |  | 201 | 		case 'lichens' :
 | 
        
           |  |  | 202 | 			this.utils.chargerFormPlantesOuLichens( squelette, nomSquelette );
 | 
        
           |  |  | 203 | 			break;
 | 
        
           |  |  | 204 | 		case 'arbres' :
 | 
        
           |  |  | 205 | 		default :
 | 
        
           |  |  | 206 | 			this.chargerObsUtilisateur( squelette );
 | 
        
           |  |  | 207 | 		break;
 | 
        
           |  |  | 208 | 	}
 | 
        
           |  |  | 209 | };
 | 
        
           |  |  | 210 |   | 
        
           |  |  | 211 | /**
 | 
        
           |  |  | 212 |  * Infos des obs arbres de cet utilisateur
 | 
        
           |  |  | 213 |  */
 | 
        
           |  |  | 214 | WidgetApa.prototype.chargerObsUtilisateur = function( formReleve ) {
 | 
        
           |  |  | 215 | 	const lthis = this;
 | 
        
           |  |  | 216 | 	const urlObs = $( 'body' ).data( 'obs-list' ) + '/' + this.infosUtilisateur.id;
 | 
        
           |  |  | 217 | 	$( '#bouton-nouveau-releve' ).removeClass( 'hidden' );
 | 
        
           |  |  | 218 |   | 
        
           |  |  | 219 | 	$.ajax({
 | 
        
           |  |  | 220 | 		url: urlObs,
 | 
        
           |  |  | 221 | 		type: 'GET',
 | 
        
           |  |  | 222 | 		success: function( dataObs, textStatus, jqXHR ) {
 | 
        
           |  |  | 223 | 			if ( !lthis.utils.valOk( dataObs ) ) {
 | 
        
           |  |  | 224 | 				dataObs = '';
 | 
        
           |  |  | 225 | 			}
 | 
        
           |  |  | 226 | 			lthis.preformaterDonneesObs( dataObs );
 | 
        
           |  |  | 227 | 		},
 | 
        
           |  |  | 228 | 		error: function( jqXHR, textStatus, errorThrown ) {
 | 
        
           |  |  | 229 | 			alert( lthis.utils.msgTraduction( 'erreur-chargement-obs-utilisateur' ) );
 | 
        
           |  |  | 230 | 		}
 | 
        
           |  |  | 231 | 	})
 | 
        
           |  |  | 232 | 	.always( function() {
 | 
        
           |  |  | 233 | 		$( '#charger-form' ).html( formReleve );
 | 
        
           |  |  | 234 | 	});
 | 
        
           |  |  | 235 | };
 | 
        
           |  |  | 236 |   | 
        
           |  |  | 237 | /**
 | 
        
           |  |  | 238 |  * Préformater les données des obs d'un utilisateur
 | 
        
           |  |  | 239 |  */
 | 
        
           |  |  | 240 | WidgetApa.prototype.preformaterDonneesObs = function( dataObs ) {
 | 
        
           |  |  | 241 | 	const lthis = this;
 | 
        
           |  |  | 242 | 	if ( this.utils.valOk( dataObs ) ) {
 | 
        
           |  |  | 243 | 		var apaObs     = [],
 | 
        
           |  |  | 244 | 			datRuComun = [],
 | 
        
           |  |  | 245 | 			obsArbres  = [],
 | 
        
           |  |  | 246 | 			apaObsE    = {},
 | 
        
           |  |  | 247 | 			count      = 0;
 | 
        
           |  |  | 248 |   | 
        
           |  |  | 249 | 		$.each( dataObs, function( i, obs ) {
 | 
        
           | 3409 | idir | 250 | 			if(  /WidgetSaisie,apa/.test( obs.mots_cles_texte ) && !/(:?plantes|lichens)/.test( obs.mots_cles_texte ) ) {
 | 
        
           | 3392 | delphine | 251 | 				if ( lthis.utils.valOk( obs.obs_etendue ) ) {
 | 
        
           |  |  | 252 | 					$.each( obs.obs_etendue, function( indice, obsE ) {
 | 
        
           |  |  | 253 | 						apaObsE[obsE.cle] = obsE.valeur;
 | 
        
           |  |  | 254 | 					});
 | 
        
           |  |  | 255 | 				}
 | 
        
           |  |  | 256 | 				obs.date_observation = $.trim( obs.date_observation.replace( /[0-9]{2}:[0-9]{2}:[0-9]{2}$/, '') );
 | 
        
           |  |  | 257 | 				if ( -1 === datRuComun.indexOf( obs.date_observation + apaObsE.rue + obs.zone_geo )  ) {
 | 
        
           |  |  | 258 | 					datRuComun.push( obs.date_observation + apaObsE.rue + obs.zone_geo );
 | 
        
           |  |  | 259 | 					apaObs[count] = lthis.utils.formaterReleveData( { 'obs':obs, 'obsE':apaObsE } );
 | 
        
           |  |  | 260 | 					count++;
 | 
        
           |  |  | 261 | 				}
 | 
        
           |  |  | 262 | 				obsArbres.push( lthis.utils.formaterArbreData( { 'obs':obs, 'obsE':apaObsE } ) );
 | 
        
           |  |  | 263 | 				apaObsE = [];
 | 
        
           |  |  | 264 | 			}
 | 
        
           |  |  | 265 | 		});
 | 
        
           |  |  | 266 | 		// on insert les arbres dans les relevés en fonction de la date et la rue d'observation
 | 
        
           |  |  | 267 | 		// car les arbres pour un relevé (date/rue) n'ont pas forcément été enregistrés dans l'ordre ni le même jour
 | 
        
           |  |  | 268 | 		$.each( obsArbres, function( indexArbre, arbre ) {
 | 
        
           |  |  | 269 | 			for ( var indexReleve = 0; indexReleve < datRuComun.length; indexReleve++ ) {
 | 
        
           |  |  | 270 | 				if ( arbre.date_rue_commune  === datRuComun[indexReleve] ) {
 | 
        
           |  |  | 271 | 					apaObs[indexReleve].push( arbre );
 | 
        
           |  |  | 272 | 				}
 | 
        
           |  |  | 273 | 			}
 | 
        
           |  |  | 274 | 		});
 | 
        
           |  |  | 275 | 		if ( this.utils.valOk( apaObs ) ) {
 | 
        
           |  |  | 276 | 			this.prechargerLesObs( apaObs );
 | 
        
           |  |  | 277 | 			$( '#apa-obs' ).val( JSON.stringify( apaObs ) );
 | 
        
           |  |  | 278 | 			$( '#bouton-list-releves' ).removeClass( 'hidden' );
 | 
        
           |  |  | 279 | 		}
 | 
        
           |  |  | 280 | 		$( '#dates-rues-communes' ).val( JSON.stringify( datRuComun ) );
 | 
        
           |  |  | 281 | 	}
 | 
        
           |  |  | 282 | };
 | 
        
           |  |  | 283 |   | 
        
           |  |  | 284 | WidgetApa.prototype.prechargerLesObs = function( apaObs ) {
 | 
        
           |  |  | 285 | 	const lthis = this;
 | 
        
           |  |  | 286 | 	const $listReleve = $( '#list-releves' );
 | 
        
           |  |  | 287 | 	const TEXT_ARBRE = ' ' + this.utils.msgTraduction( 'arbre' ).toLowerCase();
 | 
        
           |  |  | 288 |   | 
        
           |  |  | 289 | 	var nbArbres   = '',
 | 
        
           |  |  | 290 | 		texteArbre = '';
 | 
        
           |  |  | 291 |   | 
        
           |  |  | 292 | 	var releveHtml = '';
 | 
        
           |  |  | 293 | 	$( '#bouton-list-releves' )
 | 
        
           |  |  | 294 | 		.removeClass( 'hidden' )
 | 
        
           |  |  | 295 | 		.click( function() {
 | 
        
           |  |  | 296 | 			$( '#table-releves' ).removeClass( 'hidden' );
 | 
        
           |  |  | 297 | 			$( this ).addClass( 'hidden' );
 | 
        
           |  |  | 298 | 	});
 | 
        
           |  |  | 299 |   | 
        
           |  |  | 300 | 	$.each( apaObs, function( i, releve ) {
 | 
        
           |  |  | 301 | 		nbArbres = releve.length - 1;
 | 
        
           |  |  | 302 | 		texteArbre = ( 1 < nbArbres ) ? ( TEXT_ARBRE + 's' ) : TEXT_ARBRE;
 | 
        
           |  |  | 303 | 		releveHtml +=
 | 
        
           |  |  | 304 | 			'<tr class="table-light text-center">'+
 | 
        
           |  |  | 305 | 				'<td>' +
 | 
        
           |  |  | 306 | 					'<p>'+
 | 
        
           |  |  | 307 | 						lthis.utils.fournirDate( releve[0].date ) +
 | 
        
           |  |  | 308 | 					'</p><p>'+
 | 
        
           |  |  | 309 | 						releve[0].rue + ', ' + releve[0]['commune-nom'] +
 | 
        
           |  |  | 310 | 					'</p><p>'+
 | 
        
           |  |  | 311 | 						'(' + nbArbres + texteArbre + ')' +
 | 
        
           |  |  | 312 | 					'</p>'+
 | 
        
           |  |  | 313 | 				'</td>'+
 | 
        
           |  |  | 314 | 				'<td class="d-flex flex-column">' +
 | 
        
           |  |  | 315 | 					'<div class="charger-releve btn btn-sm btn-info mb-1" data-releve="' + i + '" data-load="arbres">'+
 | 
        
           |  |  | 316 | 						'<i class="fas fa-clone"></i> ' + lthis.utils.msgTraduction( 'dupliquer' )+
 | 
        
           |  |  | 317 | 					'</div> '+
 | 
        
           |  |  | 318 | 					'<div class="saisir-plantes btn btn-sm btn-info mb-1" data-releve="' + i + '" data-load="plantes">'+
 | 
        
           |  |  | 319 | 						'<i class="fas fa-seedling"></i> ' + lthis.utils.msgTraduction( 'saisir-plantes' )+
 | 
        
           |  |  | 320 | 					'</div> '+
 | 
        
           |  |  | 321 | 					'<div class="saisir-lichens btn btn-sm btn-info" data-releve="' + i + '" data-load="lichens">'+
 | 
        
           |  |  | 322 | 						// '<i class="fas fa-certificate"></i> ' + lthis.utils.msgTraduction( 'saisir-lichens' )+
 | 
        
           |  |  | 323 | 						'<i class="far fa-snowflake"></i> ' + lthis.utils.msgTraduction( 'saisir-lichens' )+
 | 
        
           |  |  | 324 | 					'</div> '+
 | 
        
           |  |  | 325 | 				'</td>'+
 | 
        
           |  |  | 326 | 			'</tr>';
 | 
        
           |  |  | 327 | 	});
 | 
        
           |  |  | 328 | 	$listReleve.append( releveHtml );
 | 
        
           |  |  | 329 | 	$( '#nb-releves-bienvenue' )
 | 
        
           |  |  | 330 | 		.removeClass( 'hidden' )
 | 
        
           |  |  | 331 | 		.find( 'span.nb-releves' )
 | 
        
           |  |  | 332 | 			.text( apaObs.length );
 | 
        
           |  |  | 333 | };
 |