diff --git a/lg/members_en.txt b/lg/members_en.txt index e6f63084e9a7230801eb97249463de2ed78f4aaf..c7609eb4b9437bcb8edd5cc7d2dca70fbfe637ef 100755 --- a/lg/members_en.txt +++ b/lg/members_en.txt @@ -9,7 +9,8 @@ ORDER_BY in the following order ASC ascending DESC descending SUBMIT_BUTTON submit -CHECKBOX_PENDING_SIGS Include pending certifications. +CHECKBOX_PENDING_SIGS Include pending certifications +CHECKBOX_MODE_SIG Print emitted certifications (Instead of received certifications) LEGEND_AVAILABILITY [availability : means this certification may already be written in the next block.] CURRENT_BLOCKCHAIN_TIME Current blockchain time TABLE_TITLE Members that will expire in less than @@ -18,11 +19,15 @@ COL_UID uid COL_IDTY_WRITTEN_TIME identity written time COL_LAST_RENEWAL last renewal COL_EXPIRE_MEMBERSHIP expire membership +COL_DISTANCE distance +COL_DISTANCE_isOutdistanced KO +COL_DISTANCE_isNotOutdistanced OK COL_LIST_RECEIVED_CERT list received certifications COL_LIST_EMITTED_CERT list emitted certifications LAST2OLDEST récentes -> anciennes OLDEST2LAST anciennes -> récentes EMITTED emitted WRITTEN written +CERT_AVAILABLE available OVERALL Overall MEMBERS members \ No newline at end of file diff --git a/lg/members_fr.txt b/lg/members_fr.txt index 83798b70d722b115dd79aa89fd4672aef31a6157..c2db83b8c994d56642ed2e704c94e9f5afff3c8a 100755 --- a/lg/members_fr.txt +++ b/lg/members_fr.txt @@ -1,6 +1,6 @@ FORM1 jours - tri par SORT_BY_IDTY_WRITTEN date d'obtention du statut de membre -SORT_BY_EXPIRE_MEMBERSHIP date d\'expiration du membership +SORT_BY_EXPIRE_MEMBERSHIP date d'expiration du membership SORT_LAST_RENEWAL date de dernier renouvellement SORT_BY_OLDEST_SIG date de plus vielle certification SORT_BY_LAST_SIG date de plus récente certification @@ -9,7 +9,8 @@ ORDER_BY dans l'ordre ASC croissant DESC décroissant SUBMIT_BUTTON recharger -CHECKBOX_PENDING_SIGS Inclure les certifications en piscine. +CHECKBOX_PENDING_SIGS Inclure les certifications en piscine +CHECKBOX_MODE_SIG Afficher les certifications émises (à la place des certifications reçus) LEGEND_AVAILABILITY [disponibilité : date à partir de laquelle cette certification pourra être écrite compte tenu de sigPeriod] CURRENT_BLOCKCHAIN_TIME Temps Blockchain actuel TABLE_TITLE Membres dont le statut de membre va expirer dans moins de @@ -18,11 +19,15 @@ COL_UID uid COL_IDTY_WRITTEN_TIME obtention statut membre COL_LAST_RENEWAL dernier renouvellement COL_EXPIRE_MEMBERSHIP date d'expiration du membre +COL_DISTANCE distance +COL_DISTANCE_isOutdistanced KO +COL_DISTANCE_isNotOutdistanced OK COL_LIST_RECEIVED_CERT liste des certifications reçues -COL_LIST_EMMITED_CERT liste des certifications émises +COL_LIST_EMITTED_CERT liste des certifications émises LAST2OLDEST récentes -> anciennes OLDEST2LAST anciennes -> récentes EMITTED émise WRITTEN écrite +CERT_AVAILABLE disponible OVERALL Total MEMBERS membres \ No newline at end of file diff --git a/package.json b/package.json index 5eb67f1ba8fa46cb04f1853e9552f05919e11cf2..22ca8c5fb19c2b2b9e85c0b134c8d24f0c22ffdb 100755 --- a/package.json +++ b/package.json @@ -20,13 +20,14 @@ "rimraf": "^2.6.1", "tmp": "^0.0.31", "underscore": "1.8.3", + "wotb": "^0.6.2", "ws": "1.1.1" }, "devDependencies": { "duniter": "1.3.9", - "duniter-keypair": "1.3.x", "duniter-bma": "1.3.x", "duniter-crawler": "1.3.x", + "duniter-keypair": "1.3.x", "duniter-prover": "1.3.x" }, "peerDependencies": { diff --git a/routes/members.js b/routes/members.js index 043ce0ff437d4b3b9f7e2ac29e00debe730b086b..de44f4fbb9376ec0c309339714045150b3e059ad 100755 --- a/routes/members.js +++ b/routes/members.js @@ -1,6 +1,8 @@ "use strict"; const co = require('co') +const wotb = require('wotb') + const timestampToDatetime = require(__dirname + '/../lib/timestampToDatetime') module.exports = (req, res, next) => co(function *() { @@ -8,16 +10,17 @@ module.exports = (req, res, next) => co(function *() { var { duniterServer, sigValidity, msValidity, sigWindow, idtyWindow, cache } = req.app.locals try { - - // get blockchain timestamp - let resultQueryCurrentBlock = yield duniterServer.dal.peerDAL.query('SELECT `medianTime` FROM block ORDER BY `medianTime` DESC LIMIT 1 '); - const currentBlockchainTimestamp = resultQueryCurrentBlock[0].medianTime; + // Initaliser les constantes + const conf = duniterServer.conf; + const head = yield duniterServer.dal.getCurrentBlockOrNull(); + const currentBlockchainTimestamp = head ? head.medianTime : 0; + const membersCount = head ? head.membersCount : 0; + const dSen = Math.ceil(Math.pow(membersCount, 1 / conf.stepMax)); // Initaliser les variables var contenu = ""; var membersIdentity = []; var membersFirstCertifExpire = []; - var membersIssuerFirstCertif = []; var membersCertifsList = []; var membersPendingCertifsList = []; var membershipsTimeList = []; @@ -25,14 +28,18 @@ module.exports = (req, res, next) => co(function *() { var membershipsExpireTimeList = []; // Récupéré les paramètres - var days = req.query.d || 400// Valeur par défaut + var days = req.query.d || 400 // Valeur par défaut + var mode = req.query.mode || 'received' // Valeur par défaut var order = req.query.d && req.query.order || 'desc' // Valeur par défaut var sort_by = req.query.sort_by || "idtyWritten" // Valeur par défaut var pendingSigs = req.query.pendingSigs || "no"; var format = req.query.format || 'HTML'; + // Alimenter wotb avec la toile actuelle + const wotbInstance = wotb.newFileInstance(duniterServer.home + '/wotb.bin'); + // Récupérer la liste des identités ayant actuellement le statut de membre - const membersList = yield duniterServer.dal.peerDAL.query('SELECT `uid`,`pub`,`member`,`written_on` FROM i_index WHERE `member`=1'); + const membersList = yield duniterServer.dal.peerDAL.query('SELECT `uid`,`pub`,`member`,`written_on`,`wotb_id` FROM i_index WHERE `member`=1'); // Récupérer pour chaque identité, le numéro du block d'écriture du dernier membership // Ainsi que la première ou dernière certification @@ -55,34 +62,52 @@ module.exports = (req, res, next) => co(function *() { let resultQueryTimeWrittenIdty = yield duniterServer.dal.peerDAL.query( 'SELECT `medianTime` FROM block WHERE `number`=\''+blockstampIdtyWritten[0]+'\' LIMIT 1') + // Tester la distance + let tmpWot = wotbInstance.memCopy(); + //let tmpWot = duniterServer.dal.wotb.memCopy(); + + //let detailedDistance = tmpWot.detailedDistance(pendingIdtyWID, dSen, conf.stepMax, conf.xpercent); + //let isOutdistanced = detailedDistance.isOutdistanced; + let isOutdistanced = tmpWot.isOutdistanced(membersList[m].wotb_id, dSen, conf.stepMax, conf.xpercent); + // Stocker les informations de l'identité membersIdentity.push({ writtenBloc: blockstampIdtyWritten[0], - writtenTimestamp: resultQueryTimeWrittenIdty[0].medianTime + writtenTimestamp: resultQueryTimeWrittenIdty[0].medianTime, + isOutdistanced: isOutdistanced }); - // récupérer toutes les certification reçus par l'utilisateur + // récupérer toutes les certification reçus/émises par l'utilisateur let tmpQueryCertifsList = []; - if (sort_by == "lastSig") + let tmpOrder = (sort_by == "lastSig") ? 'DESC' : 'ASC'; + if (mode == 'emitted') { tmpQueryCertifsList = yield duniterServer.dal.peerDAL.query( - 'SELECT `issuer`,`written_on`,`expires_on` FROM c_index WHERE `receiver`=\''+membersList[m].pub+'\' ORDER BY `expires_on` DESC'); + 'SELECT `receiver`,`written_on`,`expires_on` FROM c_index WHERE `issuer`=\''+membersList[m].pub+'\' ORDER BY `expires_on` '+tmpOrder); } else { - tmpQueryCertifsList = yield duniterServer.dal.peerDAL.query( - 'SELECT `issuer`,`written_on`,`expires_on` FROM c_index WHERE `receiver`=\''+membersList[m].pub+'\' ORDER BY `expires_on` ASC'); + tmpQueryCertifsList = yield duniterServer.dal.peerDAL.query( + 'SELECT `issuer`,`written_on`,`expires_on` FROM c_index WHERE `receiver`=\''+membersList[m].pub+'\' ORDER BY `expires_on` '+tmpOrder); } - // Calculer le nombre de certifications reçus par le membre courant + // Calculer le nombre de certifications reçus/émises par le membre courant let nbWrittenCertifs = tmpQueryCertifsList.length; - // Récupérer les uid des émetteurs des certifications reçus par l'utilisateur + // Récupérer les uid des émetteurs/receveurs des certifications reçus/émises par l'utilisateur // Et stocker les uid et dates d'expiration dans un tableau membersCertifsList[m] = new Array(); for (var i=0;i<nbWrittenCertifs;i++) { - let tmpQueryGetUidIssuerCert = yield duniterServer.dal.peerDAL.query('SELECT `uid` FROM i_index WHERE `pub`=\''+tmpQueryCertifsList[i].issuer+'\' LIMIT 1'); + let tmpQueryGetUidProtagonistCert + if (mode == 'emitted') + { + tmpQueryGetUidProtagonistCert = yield duniterServer.dal.peerDAL.query('SELECT `uid` FROM i_index WHERE `pub`=\''+tmpQueryCertifsList[i].receiver+'\' LIMIT 1'); + } + else + { + tmpQueryGetUidProtagonistCert = yield duniterServer.dal.peerDAL.query('SELECT `uid` FROM i_index WHERE `pub`=\''+tmpQueryCertifsList[i].issuer+'\' LIMIT 1'); + } let tmpBlockWrittenOn = tmpQueryCertifsList[i].written_on.split("-"); // Stoker la liste des certifications qui n'ont pas encore expirées @@ -90,11 +115,11 @@ module.exports = (req, res, next) => co(function *() { { if (i == 0) { - membersIssuerFirstCertif.push(tmpQueryGetUidIssuerCert[0].uid); - membersFirstCertifExpire.push(tmpQueryCertifsList[0].expires_on); + membersFirstCertifExpire.push(tmpQueryCertifsList[0].expires_on); } membersCertifsList[m].push({ - issuer: tmpQueryGetUidIssuerCert[0].uid, + issuer: (mode=='emitted') ? membersList[m].uid:tmpQueryGetUidProtagonistCert[0].uid, + receiver: (mode!='emitted') ? membersList[m].uid:tmpQueryGetUidProtagonistCert[0].uid, writtenBloc: tmpBlockWrittenOn[0], timestampExpire: tmpQueryCertifsList[i].expires_on }); @@ -103,19 +128,20 @@ module.exports = (req, res, next) => co(function *() { // SI LES CERTIFICATIONS EN PISCINE SONT DEMANDÉES let nbValidPendingCertifs = 0; + if (pendingSigs == "yes") { - // récupérer toutes les certification en piscine destinées à l'utilisateur + // récupérer toutes les certification en piscine let tmpQueryPendingCertifsList = []; - if (sort_by == "lastSig") + if (mode == 'emitted') { tmpQueryPendingCertifsList = yield duniterServer.dal.peerDAL.query( - 'SELECT `from`,`block_number`,`expires_on` FROM certifications_pending WHERE `to`=\''+membersList[m].pub+'\' ORDER BY `expires_on` DESC'); + 'SELECT `from`,`to`,`block_number`,`expires_on` FROM certifications_pending WHERE `from`=\''+membersList[m].pub+'\' ORDER BY `expires_on` '+tmpOrder); } else { tmpQueryPendingCertifsList = yield duniterServer.dal.peerDAL.query( - 'SELECT `from`,`block_number`,`expires_on` FROM certifications_pending WHERE `to`=\''+membersList[m].pub+'\' ORDER BY `expires_on` ASC'); + 'SELECT `from`,`block_number`,`expires_on` FROM certifications_pending WHERE `to`=\''+membersList[m].pub+'\' ORDER BY `expires_on` '+tmpOrder); } // Calculer le nombre de certifications en attentes destinées au membre courant @@ -126,24 +152,26 @@ module.exports = (req, res, next) => co(function *() { membersPendingCertifsList[m] = new Array(); for (var i=0;i<nbPendingCertifs;i++) { - let tmpQueryGetUidIssuerPendingCert = yield duniterServer.dal.peerDAL.query('SELECT `uid` FROM i_index WHERE `pub`=\''+tmpQueryPendingCertifsList[i].from+'\' LIMIT 1'); + let tmpPub = (mode=='emitted') ? tmpQueryPendingCertifsList[i].to:tmpQueryPendingCertifsList[i].from; + let tmpQueryGetUidProtagonistPendingCert = yield duniterServer.dal.peerDAL.query('SELECT `uid` FROM i_index WHERE `pub`=\''+tmpPub+'\' LIMIT 1'); + // Vérifier que l'émetteur de la certification correspond à une identié connue - if ( tmpQueryGetUidIssuerPendingCert.length > 0 ) + if ( tmpQueryGetUidProtagonistPendingCert.length > 0 ) { - // récupérer le timestamp d'écriture de la dernière certification écrite par l'émetteur - let tmpQueryLastIssuerCert = yield duniterServer.dal.peerDAL.query('SELECT `chainable_on` FROM c_index WHERE `issuer`=\''+tmpQueryPendingCertifsList[i].from+'\' ORDER BY `expires_on` DESC LIMIT 1'); - - // Stoker la liste des certifications en piscine qui n'ont pas encore expirées - if (tmpQueryPendingCertifsList[i].expires_on > currentBlockchainTimestamp) - { - membersPendingCertifsList[m].push({ - from: tmpQueryGetUidIssuerPendingCert[0].uid, - blockNumber: tmpQueryPendingCertifsList[i].block_number, - timestampExpire: tmpQueryPendingCertifsList[i].expires_on, - timestampWritable: (tmpQueryLastIssuerCert[0].chainable_on) - }); - nbValidPendingCertifs++; - } + // récupérer le timestamp d'écriture de la dernière certification écrite par l'émetteur + let tmpQueryLastIssuerCert = yield duniterServer.dal.peerDAL.query('SELECT `chainable_on` FROM c_index WHERE `issuer`=\''+tmpQueryPendingCertifsList[i].from+'\' ORDER BY `expires_on` DESC LIMIT 1'); + + // Stoker la liste des certifications en piscine qui n'ont pas encore expirées + if (tmpQueryPendingCertifsList[i].expires_on > currentBlockchainTimestamp) + { + membersPendingCertifsList[m].push({ + protagonist: tmpQueryGetUidProtagonistPendingCert[0].uid, + blockNumber: tmpQueryPendingCertifsList[i].block_number, + timestampExpire: tmpQueryPendingCertifsList[i].expires_on, + timestampWritable: (typeof(tmpQueryLastIssuerCert[0]) == 'undefined') ? 0:tmpQueryLastIssuerCert[0].chainable_on + }); + nbValidPendingCertifs++; + } } } } @@ -168,8 +196,8 @@ module.exports = (req, res, next) => co(function *() { } // Initialiser le tableau membersListOrdered - var membersListOrdered = [ [] ]; - var membersCertifsListSorted = [ [] ]; + var membersListOrdered = []; + var membersCertifsListSorted = []; // Calculer le timestamp limite à prendre en compte var limitTimestamp = currentBlockchainTimestamp + (days*86400); @@ -231,11 +259,13 @@ module.exports = (req, res, next) => co(function *() { lastRenewalWrittenBloc: membershipsBlockNumberList[idMaxTime], expireMembershipTimestamp: membershipsExpireTimeList[idMaxTime], certifications: membersCertifsList[idMaxTime], - pendingCertifications: membersPendingCertifsList[idMaxTime] + pendingCertifications: membersPendingCertifsList[idMaxTime], + isOutdistanced: membersIdentity[idMaxTime].isOutdistanced }); membersCertifsListSorted.push({ issuer: membersCertifsList[idMaxTime].issuer, + receiver: membersCertifsList[idMaxTime].receiver, writtenBloc: membersCertifsList[idMaxTime].writtenBloc, timestampExpire: membersCertifsList[idMaxTime].timestampExpire }); @@ -257,7 +287,7 @@ module.exports = (req, res, next) => co(function *() { res.locals = { host: req.headers.host.toString(), - days, sort_by, order, + days, mode, sort_by, order, pendingSigs, currentBlockchainTimestamp, diff --git a/routes/willMembers.js b/routes/willMembers.js index 6cc14b8ea185e2725d4bc1dc901fb3fb4f29462e..ea865b81d50346050735159f95d2e98107d66f81 100755 --- a/routes/willMembers.js +++ b/routes/willMembers.js @@ -2,7 +2,7 @@ const co = require('co') const crypto = require('crypto') -//const wotb = require('wotb') +const wotb = require('wotb') const timestampToDatetime = require(__dirname + '/../lib/timestampToDatetime') @@ -56,8 +56,8 @@ module.exports = (req, res, next) => co(function *() { countMembersWithSigQtyValidCert = 0; lastUpgradeTime = Math.floor(Date.now() / 1000); - // Alimenter wotb avec la toile Ğ1 - //const wotbInstance = wotb.newFileInstance(duniterServer.home + '/wotb.bin'); + // Alimenter wotb avec la toile actuelle + const wotbInstance = wotb.newFileInstance(duniterServer.home + '/wotb.bin'); // Récupérer la liste des identités en piscine const resultQueryIdtys = yield duniterServer.dal.peerDAL.query('SELECT `buid`,`pubkey`,`uid`,`hash`,`expires_on` FROM identities_pending WHERE `member`=0'); @@ -282,20 +282,21 @@ module.exports = (req, res, next) => co(function *() { if (!doubloon) { // Tester la distance à l'aide des certifications disponibles - //let wotb = wotbInstance.memCopy(); - let wotb = duniterServer.dal.wotb.memCopy(); + let tmpWot = wotbInstance.memCopy(); + //let tmpWot = duniterServer.dal.wotb.memCopy(); - let pendingIdtyWID = wotb.addNode() + let pendingIdtyWID = tmpWot.addNode(); for (const cert of idtysPendingCertifsList[idMax]) { - wotb.addLink(cert.wid, pendingIdtyWID) + tmpWot.addLink(cert.wid, pendingIdtyWID); } - let detailedDistance = wotb.detailedDistance(pendingIdtyWID, dSen, conf.stepMax, conf.xpercent) + let detailedDistance = tmpWot.detailedDistance(pendingIdtyWID, dSen, conf.stepMax, conf.xpercent); let isOutdistanced = detailedDistance.isOutdistanced; - + //let isOutdistanced = tmpWot.isOutdistanced(pendingIdtyWID, dSen, conf.stepMax, conf.xpercent); + // Tester la présence de l'adhésion let membership = null - const pendingMembershipsOfIdty = yield duniterServer.dal.msDAL.getPendingINOfTarget(identitiesList[idMax].hash) + const pendingMembershipsOfIdty = yield duniterServer.dal.msDAL.getPendingINOfTarget(identitiesList[idMax].hash); for (const ms of pendingMembershipsOfIdty) { if (!membership && ms.expires_on > currentBlockchainTimestamp) { membership = ms @@ -303,7 +304,7 @@ module.exports = (req, res, next) => co(function *() { } // Nettoie la wot temporaire - wotb.clear(); + tmpWot.clear(); idtysListOrdered.push({ uid: identitiesList[idMax].uid, diff --git a/views/about.html b/views/about.html index 6e98480291c572ed2e2af81e5e4bf2d0fa7805f9..d69d04db8f637ffc80c24d6a17ef0f96c4d19b8e 100755 --- a/views/about.html +++ b/views/about.html @@ -31,7 +31,7 @@ ${(host.substr(host.length-6,6) == '.onion') ? HTML_TOR_HEAD:HTML_HEAD} <a href="https://github.com/duniter/duniter-currency-monit/blob/master/LICENSE">License AGPL V 3.0</a><br> <a href="https://github.com/duniter/duniter-currency-monit/">github repository</a> </div><br> -<div align="left">Version : <a href="https://github.com/duniter/duniter-currency-monit/releases/tag/module-0.2.11">module-0.2.11</a></div><br> +<div align="left">Version : <a href="https://github.com/duniter/duniter-currency-monit/releases/tag/module-0.2.12">module-0.2.12</a></div><br> <div align="left">Author : <a href="https://github.com/librelois">Éloïs Librelois</a></div><br> <div align="left">Contributors : <a href="https://github.com/jytou">jytou</a> (translator), <a href="https://github.com/devingfx">devingfx</a> (frontend), <a href="https://github.com/c-geek">cgeek</a> (willMembers and wotex),<a href="https://github.com/M5oul">M5oul</a> (adjustments)</div><br> <br> diff --git a/views/members.html b/views/members.html index b9472b5f2bbeb6e56d3ccc076207a3fc84036dcd..b0de78d6dc0b2751dd4217798f8d7734089e4e13 100755 --- a/views/members.html +++ b/views/members.html @@ -27,16 +27,17 @@ ${(host.substr(host.length-6,6) == '.onion') ? HTML_TOR_HEAD:HTML_HEAD} <!-- Afficher le formulaire --> <input type="number" name="d" value="${days}"/>${LANG["FORM1"]} <select name="sort_by"> <option name="sort_by" value ="idtyWritten">${LANG["SORT_BY_IDTY_WRITTEN"]} -<option name="sort_by" value ="expireMembership" ${sort_by == 'expireMembership' ? 'selected' : ''}>${LANG["SORT_BY_EXPIRE_MEMBERSHIP"]} date d\'expiration du membership -<option name="sort_by" value ="lastRenewal" ${sort_by == 'lastRenewal' ? 'selected' : ''}>${LANG["SORT_LAST_RENEWAL"]} date de dernier renouvellement -<option name="sort_by" value ="oldestSig" ${sort_by == 'oldestSig' ? 'selected' : ''}>${LANG["SORT_BY_OLDEST_SIG"]} date de plus vielle certification -<option name="sort_by" value ="lastSig" ${sort_by == 'lastSig' ? 'selected' : ''}>${LANG["SORT_BY_LAST_SIG"]} date de plus récente certification -<option name="sort_by" value ="sigCount" ${sort_by == 'sigCount' ? 'selected' : ''}>${LANG["SORT_BY_SIG_COUNT"]} nombre de certifications reçues +<option name="sort_by" value ="expireMembership" ${sort_by == 'expireMembership' ? 'selected' : ''}>${LANG["SORT_BY_EXPIRE_MEMBERSHIP"]} +<option name="sort_by" value ="lastRenewal" ${sort_by == 'lastRenewal' ? 'selected' : ''}>${LANG["SORT_LAST_RENEWAL"]} +<option name="sort_by" value ="oldestSig" ${sort_by == 'oldestSig' ? 'selected' : ''}>${LANG["SORT_BY_OLDEST_SIG"]} +<option name="sort_by" value ="lastSig" ${sort_by == 'lastSig' ? 'selected' : ''}>${LANG["SORT_BY_LAST_SIG"]} +<option name="sort_by" value ="sigCount" ${sort_by == 'sigCount' ? 'selected' : ''}>${LANG["SORT_BY_SIG_COUNT"]} </select> ${LANG["ORDER_BY"]} <select name="order"> <option name="order" value ="asc"> ${LANG["ASC"]} <option name="order" value ="desc" ${order == 'desc' ? 'selected' : ''}> ${LANG["DESC"]}</select> <input type="submit" value="envoyer"><br> -<input type="checkbox" name="pendingSigs" value="yes" ${pendingSigs == 'yes' ? 'checked' : ''}>${LANG["CHECKBOX_PENDING_SIGS"]}</form><br> +<input type="checkbox" name="pendingSigs" value="yes" ${pendingSigs == 'yes' ? 'checked' : ''}>${LANG["CHECKBOX_PENDING_SIGS"]}.<br> +<input type="checkbox" name="mode" value="emitted" ${mode == 'emitted' ? 'checked' : ''}>${LANG["CHECKBOX_MODE_SIG"]}.</form><br> <!-- Afficher la légende --> <br> @@ -55,8 +56,9 @@ ${(pendingSigs == 'yes' && help != 'no') ? ` ${LANG["LEGEND_AVAILABILITY"]}<br>` <td align="center">${LANG["COL_IDTY_WRITTEN_TIME"]}</td> <td align="center">${LANG["COL_LAST_RENEWAL"]}</td> <td align="center">${LANG["COL_EXPIRE_MEMBERSHIP"]}</td> + <td align='center'>${LANG['COL_DISTANCE']}</td> <td style="background:#000000">-</td> - <td align="left" colspan="${nbMaxCertifs}">liste des certifications reçues (${sort_by == 'lastSig' ? LANG["LAST2OLDEST"] : LANG["OLDEST2LAST"]})</td> + <td align="left" colspan="${nbMaxCertifs}">${(mode=='emitted') ? LANG['COL_LIST_EMITTED_CERT']:LANG['COL_LIST_RECEIVED_CERT']} (${sort_by == 'lastSig' ? LANG["LAST2OLDEST"] : LANG["OLDEST2LAST"]})</td> </tr> ${membersListFiltered @@ -65,27 +67,25 @@ ${(pendingSigs == 'yes' && help != 'no') ? ` ${LANG["LEGEND_AVAILABILITY"]}<br>` <tr> ${(member.proportion = proportion(member.expireMembershipTimestamp,msValidity,0,120),'')} <td align="center" style="background:hsla(${member.proportion}, 100%, 50%, 1)"> - <!--<td align="center" style="background:#${color}">--> <h3>${member.uid}</h3> ->${member.certifications.length} ${pendingSigs == "yes" && member.pendingCertifications.length > 0 ? `(${member.pendingCertifications.length})` : ''} </td> - <!--<td align="center" style="background:hsla(0, 0%, ${member.proportion}%, 1)">--> <td align="center" style="background:hsla(${member.proportion}, 100%, 50%, 1)"> - <!--<td align="center" style="background:#${color}">--> ${timestampToDatetime(member.idtyWrittenTimestamp)}<br> #${member.idtyWrittenBloc} </td> <td align="center" style="background:hsla(${member.proportion}, 100%, 50%, 1)"> - <!--<td align="center" style="background:#${color}">--> ${timestampToDatetime(member.lastRenewalTimestamp)}<br> #${member.lastRenewalWrittenBloc} </td> <td align="center" style="background:hsla(${member.proportion}, 100%, 50%, 1)"> - <!--<td align="center" style="background:#${color}">--> ${timestampToDatetime(member.expireMembershipTimestamp)}</td> + <td align='center' style="background:hsla(${member.proportion}, 100%, 50%, 1)"> + <span style="color: ${member.isOutdistanced ? 'red' : 'blue' }">${member.isOutdistanced ? LANG['COL_DISTANCE_isOutdistanced'] : LANG['COL_DISTANCE_isNotOutdistanced'] }</span> + </td> <td style="background:#000000">-</td> <!-- Printer les certifications en piscine --> @@ -93,10 +93,13 @@ ${(pendingSigs == 'yes' && help != 'no') ? ` ${LANG["LEGEND_AVAILABILITY"]}<br>` member.pendingCertifications.map( certification=> ` <!-- Printer la certification --> <td align="center" style="background:${color(certification.timestampExpire,sigWindow,200)})"> - ${certification.from}<br> + ${certification.protagonist}<br> ${timestampToDatetime(certification.timestampExpire)}<br> ${LANG["EMITTED"]} #${certification.blockNumber}<br> - [inscriptible ${timestampToDatetime(certification.timestampWritable)}] + ${(certification.timestampWritable > currentBlockchainTimestamp) ? `<font color="DarkRed">[${timestampToDatetime(certification.timestampWritable)} + `:`<font color="green">[${LANG["CERT_AVAILABLE"]}` + }] + </font> </td> `).join('') :''} @@ -105,7 +108,7 @@ ${(pendingSigs == 'yes' && help != 'no') ? ` ${LANG["LEGEND_AVAILABILITY"]}<br>` ${member.certifications.map( certification=> ` <!-- Printer la certification --> <td align="center" style="background:hsla(${proportion(certification.timestampExpire,sigValidity,0,120)}, 100%, 50%, 1 )"> - ${certification.issuer}<br> + ${(mode=='emitted') ? certification.receiver:certification.issuer}<br> ${timestampToDatetime(certification.timestampExpire)}<br> ${LANG["WRITTEN"]} #${certification.writtenBloc} </td>