Compare commits
3 Commits
a2d9cc175c
...
2598c7f8fc
Author | SHA1 | Date | |
---|---|---|---|
2598c7f8fc | |||
c5ed0343c6 | |||
b131a2400b |
@ -24,10 +24,14 @@ puis naviguer sur https://localhost:3300
|
||||
|
||||
|
||||
## Comment ça marche?
|
||||
Mettre les gtg_tasks.xml
|
||||
Mettre les gtg_tasks.xml et tags.xml dans le dossier source.
|
||||
Lancer le serveur node,
|
||||
aller sur
|
||||
http://localhost:3300
|
||||
|
||||
|
||||
Ce serveur va lire un fichier dans le dossier source, celui des tâches de GTG, puis en faire un json, et en sortir des statistiques dans une page web.
|
||||
|
||||
Ce serveur va lire un fichier dans le dossier **source**, celui des tâches de GTG, puis en faire un json, et en sortir des statistiques dans une page web ainsi qu'un fichier markdown dans le dossier **output**.
|
||||
|
||||
|
||||
## sources
|
||||
|
@ -1 +1,259 @@
|
||||
# Export de Tags GTG du 02/03/2021 à 11:09:59
|
||||
# Export de Tâches GTG
|
||||
date: 02/03/2021 à 12:24:30
|
||||
# Rapport hebdomadaire de dev
|
||||
## 8 ont été fermées
|
||||
* node
|
||||
* agenda du libre
|
||||
* faire une page qui donne les infos d'un commerce via addok
|
||||
* mettre un store vuex
|
||||
* @cil faire la page de chiffrement et déchiffrement sur @framadate
|
||||
* tester le speech to text de mozilla common voice
|
||||
* * trouver où sont stockées les données de GTG
|
||||
* * les ajouter au backup borg
|
||||
|
||||
---
|
||||
|
||||
# Rapport des tâches durant les 7 derniers jours
|
||||
|
||||
## 29 ont été fermées
|
||||
|
||||
* Boulot
|
||||
* node
|
||||
* voix du nucléaire
|
||||
* contacter une boite pour faire un devis @mail ou @tel
|
||||
* rdv conf jitsi avec Myrto
|
||||
* agenda du libre
|
||||
* faire une page qui donne les infos d'un commerce via addok
|
||||
* ménage dans nextcloud, dédupliquer et ne garder que les textes, les assos, et osm @spaceship
|
||||
* @nas décharger le dossier home vers le bazar de @spaceship @backup @archives
|
||||
* enlever les dossiers de backup de Drive
|
||||
* faire un borg @backup sur le @nas
|
||||
* mettre un store vuex
|
||||
* rdv @tel déchetterie pour les cartons
|
||||
* copier les dossiers de @backup de prod de @fatland dans le nas
|
||||
* copier les musiques du NAS dans spaceship @backup
|
||||
* @cil faire la page de chiffrement et déchiffrement sur @framadate
|
||||
* tester le speech to text de mozilla common voice
|
||||
* contacter le support de PCW @tel
|
||||
* * trouver où sont stockées les données de GTG
|
||||
* * les ajouter au backup borg
|
||||
* demander paiement
|
||||
* renouveller les papiers sur malt
|
||||
* demander validation des jours pour février par @mail a Thierry
|
||||
* commander resto chat botté
|
||||
* scotch électrique veilleuses du breau
|
||||
* les appeler @tel
|
||||
* envoyer pitch de présentation OSM à krys
|
||||
* trouver un contact @tel pour assurance pacifica, regarder sur une facture assurance voiture
|
||||
* fatland extraire les textes non syncronisés avec nextcloud
|
||||
## 68 ont été ouvertes
|
||||
|
||||
* noter les anniv de la famille fontenay
|
||||
* faire un mail de suivi à la liste edu concernant le podcast libre à vous @mail
|
||||
* nextcloud prob avec les pdf
|
||||
* choisir un spot lumineux pour le sapin
|
||||
* voir pour une selle plus confortable @vélo @achat
|
||||
* réparer la commande via interrupteur enocean
|
||||
* syncro dans le NAS après un borg backup du spaceship
|
||||
* dédupliquer la musique sur @spaceship
|
||||
* trouver une chiffroparty sur l'agenda du libre / mobilizon
|
||||
* faire compte du mois après paiement de mission
|
||||
* voir Estelle et compagnie
|
||||
* @badoune accès à son site
|
||||
* ajout de typo dans ubuntu
|
||||
* ranger les tâches de la semaine dans un tag @grosse_pierre
|
||||
* essayer freecad pour faire une maison
|
||||
* monter video accéléré osm forêt mapping
|
||||
* monter les dossiers de serveurs distants sur un dossier de catwoman @spaceship
|
||||
* @framadate @symfony rétablir l'api framadate sur @sys
|
||||
* persister un sondage : enregistrer le cas de choix identiques pour tous les choix
|
||||
* @frontend @framadate style de formulaire selon les maquettes posant les questions
|
||||
* @frontend enregistrer un objet de forulaire localement
|
||||
* faire marcher l'api framadate localement en php8
|
||||
* mettre icinga sur le @vps
|
||||
* monitorer avec icinga les différents serveurs par un ping
|
||||
* prendre un bearer token de connec
|
||||
* lancer la mutation GraphQl de création d'event
|
||||
* faire marcher localement l'import d'event en masse
|
||||
* réinstall la bdd postgresql sur @spaceship
|
||||
* bitwarden dédupliquer grâce à keepass
|
||||
* @blog présentation du transcripteur vosk @media
|
||||
* @backup faire marcher syncthing correctement entre @spaceship et @cloud et @spare
|
||||
* @edu @gtg regarder la doc de recherche
|
||||
* étudier ajout de @nextcloud pour les @voixdunuc
|
||||
* @vosk transcription améliorer le script de conversion de tous les inputs
|
||||
* participer à une visio chiffrofête
|
||||
* @edu tester emacs et orgmode
|
||||
* @nas ranger les vidéos du dossier docu conf youtube
|
||||
* sauvegarder les vidéos du @nas sur un disque externe
|
||||
* chaussons
|
||||
* drap lit de Fao
|
||||
* serveur node en backend pour s'authentifier
|
||||
* appel oauth
|
||||
* carte resto à faire
|
||||
* envoi du mail suivi réparation par email @mail à support@pcw.fr
|
||||
* importer les entités dans le dépot sf5
|
||||
* remplacer le contenu du dépot date-poll-api par celui de sf5
|
||||
* mettre à jour les prérequis de dépendance avec php8
|
||||
* config docker
|
||||
* @osm mettre à jour déchetterie https://wiki.openstreetmap.org/wiki/Tag:amenity%3Drecycling
|
||||
* mission en cours HigcoBox
|
||||
* matomo check sur pages du staging
|
||||
* intercom passer par node
|
||||
* générer un fichier d'env pour le staging
|
||||
* regarder des sites de mission logiciel libre https://www.libre-entreprise.org/
|
||||
* exporter la liste de mes titres likés sur spotify avec un coup de wget
|
||||
* stopper mon abonnement spotify
|
||||
* envoyer à novaa par @mail les papiers fiscalité axa
|
||||
* fin de @mission
|
||||
* @cil atelier libération de tel des gafam
|
||||
https://mypads.framapad.org/mypads/?/mypads/group/cil-gometz-0vj64720/pad/view/telephones-libres-ejj847vy
|
||||
|
||||
* proposer libre en fête
|
||||
* gestion d'assurance
|
||||
* récupérer recommandé a la poste avant 17h30
|
||||
* écrire un exportateur de tâches de GTD depuis GTG vers un format json
|
||||
* @dev faire un environnement de dev local @nextcloud
|
||||
* ajouter une variable matomo custom
|
||||
* matomo envoyer la valeur SC si présent dans l'url
|
||||
* faire une app de démo pour nextcloud
|
||||
* faire une page qui fasse comme cryptpad pour être déchiffrée @chiffrement @dev
|
||||
---
|
||||
# Rapport des autres tâches durant le mois
|
||||
|
||||
## 29 ont été fermées
|
||||
|
||||
## 68 ont été ouvertes
|
||||
|
||||
---
|
||||
# Stats de fermeture des tâches
|
||||
|
||||
---
|
||||
|
||||
# Export de toutes les 264 tâches ouvertes GTG
|
||||
|
||||
|
||||
---
|
||||
|
||||
# Export de toutes les 183 tâches fermées GTG
|
||||
|
||||
|
||||
|
||||
# Export de Tags GTG
|
||||
|
||||
|
||||
|
||||
* @osm , 39
|
||||
* @graph , 10
|
||||
* @forum , 2
|
||||
* @dev , 115
|
||||
* @vélo , 6
|
||||
* @écriture , 8
|
||||
* @rémunéré , 16
|
||||
* @edu , 28
|
||||
* @mail , 23
|
||||
* @vacances , 12
|
||||
* @tel , 17
|
||||
* @mobilizon , 26
|
||||
* @elec , 4
|
||||
* @pognon , 9
|
||||
* @travaux , 29
|
||||
* @administratif , 9
|
||||
* @associatif , 34
|
||||
* @serveur , 3
|
||||
* @work , 30
|
||||
* @nextcloud , 16
|
||||
* @encryption , 2
|
||||
* @untouched , 82
|
||||
* @adminsys , 16
|
||||
* @recherche , 19
|
||||
* @tasks , 5
|
||||
* @social , 14
|
||||
* @GTG , 5
|
||||
* @sys , 30
|
||||
* @vps , 5
|
||||
* @qzine , 3
|
||||
* @blog , 11
|
||||
* @solabaie , 2
|
||||
* @createrra , 1
|
||||
* @contacts , 3
|
||||
* @carnet , 1
|
||||
* @opendata , 2
|
||||
* @achat , 15
|
||||
* @cuisine , 1
|
||||
* @livre , 12
|
||||
* @achats , 0
|
||||
* @nas , 7
|
||||
* @musique , 1
|
||||
* @DL , 1
|
||||
* @nginx , 2
|
||||
* @sysadmin , 1
|
||||
* @impots , 1
|
||||
* @degfam , 1
|
||||
* @tesla , 1
|
||||
* @lecture , 13
|
||||
* @boulot , 22
|
||||
* @mastodon , 4
|
||||
* @backup , 33
|
||||
* @claire , 12
|
||||
* @famille , 11
|
||||
* @video , 3
|
||||
* @waiting_for, , 0
|
||||
* @déconfinage , 11
|
||||
* @waiting_for , 11
|
||||
* @josm , 14
|
||||
* @bot , 2
|
||||
* @scraping , 13
|
||||
* @chapril , 1
|
||||
* @jardin , 15
|
||||
* @cil-gometz , 9
|
||||
* @photo , 2
|
||||
* @fanzine , 3
|
||||
* @interview , 4
|
||||
* @audio , 2
|
||||
* @dadou , 2
|
||||
* @gtg , 2
|
||||
* @resolv , 1
|
||||
* @fibre , 1
|
||||
* @peertube , 3
|
||||
* @cloud , 2
|
||||
* @media , 2
|
||||
* @extérieur , 14
|
||||
* @voixdunuc , 5
|
||||
* @fediverse , 42
|
||||
* @admins , 0
|
||||
* @april , 3
|
||||
* @spaceship , 12
|
||||
* @ordi , 1
|
||||
* @plume , 3
|
||||
* @oauth , 9
|
||||
* @monitoring , 3
|
||||
* @bitwarden , 1
|
||||
* @archives , 2
|
||||
* @chiffrement , 14
|
||||
* @graphql , 5
|
||||
* @livestream , 3
|
||||
* @install , 1
|
||||
* @rails , 3
|
||||
* @fatland , 2
|
||||
* @courrier , 1
|
||||
* @klassroom , 2
|
||||
* @caisse , 3
|
||||
* @symfnoy , 0
|
||||
* @domoticz , 2
|
||||
* @autohébergement , 3
|
||||
* @grivery , 3
|
||||
* @framadate , 12
|
||||
* @badoune , 2
|
||||
* @grosse_pierre , 6
|
||||
* @symfony , 13
|
||||
* @inbox , 2
|
||||
* @frontend , 11
|
||||
* @spare , 1
|
||||
* framadate , 0
|
||||
* @vosk , 1
|
||||
* @rangement , 3
|
||||
* @mission , 8
|
||||
* @assurance , 3
|
||||
|
||||
rapport généré avec gtg2nodejs par tykayn - contact@cipherbliss.com
|
@ -12,6 +12,7 @@
|
||||
"fs": "0.0.1-security",
|
||||
"http-errors": "^1.6.3",
|
||||
"jade": "^1.11.0",
|
||||
"lodash": "^4.17.21",
|
||||
"morgan": "^1.9.1",
|
||||
"pug": "^3.0.0"
|
||||
},
|
||||
|
168
routes/index.js
168
routes/index.js
@ -1,12 +1,12 @@
|
||||
var express = require('express');
|
||||
var fs = require('fs');
|
||||
var _ = require('lodash');
|
||||
|
||||
var parseString = require("xml2js").parseString;
|
||||
var router = express.Router();
|
||||
var fileToOpen = 'gtg_tasks'
|
||||
|
||||
// const convertFiles = true;
|
||||
let convertFiles = false;
|
||||
let convertFiles = true;
|
||||
// let convertFiles = false;
|
||||
let computeDataOnExtract = true;
|
||||
|
||||
let jsonAllData = {
|
||||
@ -68,16 +68,56 @@ function computeData(jsonAllData) {
|
||||
|
||||
jsonAllData.stats = {
|
||||
tasksCount : jsonAllData.tasks.project.task.length,
|
||||
tasksClosed: 0,
|
||||
tasksClosed : 0,
|
||||
tasksOpen : 0,
|
||||
maxTasksCountPerTag : 0,
|
||||
maxTasksCountPerTag: 0,
|
||||
listOpen : [],
|
||||
listOpenWeekly : [],
|
||||
listOpenMonthly : [],
|
||||
listClosed : [],
|
||||
listClosedWeekly : [],
|
||||
listDevWeeklyClosed : [],
|
||||
listClosedMonthly : [],
|
||||
}
|
||||
let now = new Date();
|
||||
|
||||
for (let t of jsonAllData.tasks.project.task) {
|
||||
// console.log('t', t)
|
||||
let tags = t["$"].tags.split(',')
|
||||
// count open and closed tasks
|
||||
|
||||
let dateOfTask = new Date()
|
||||
|
||||
if (t['$'].status == 'Active') {
|
||||
jsonAllData.stats.listOpen.push(t)
|
||||
let addeddate = new Date(t.addeddate)
|
||||
let daysDiff = getNumberOfDaysDiffTwoDates(addeddate, now);
|
||||
|
||||
if (daysDiff <= 7) {
|
||||
jsonAllData.stats.listOpenWeekly.push(t)
|
||||
} else if (daysDiff >= 7 & daysDiff <= 31) {
|
||||
jsonAllData.stats.listOpenMonthly.push(t)
|
||||
}
|
||||
|
||||
} else if (t['$'].status == 'Done') {
|
||||
jsonAllData.stats.listClosed.push(t)
|
||||
let donedate = new Date(t.donedate)
|
||||
let daysDiff = getNumberOfDaysDiffTwoDates(donedate, now);
|
||||
|
||||
if (daysDiff <= 7) {
|
||||
jsonAllData.stats.listClosedWeekly.push(t)
|
||||
|
||||
// tâches uniquement de dev
|
||||
if((/\b(dev|sysadmin|écriture|edu|fediverse)\b/g).test(t['$'].tags)
|
||||
){
|
||||
jsonAllData.stats.listDevWeeklyClosed.push(t)
|
||||
}
|
||||
} else if (daysDiff >= 7 & daysDiff <= 31) {
|
||||
jsonAllData.stats.listClosedMonthly.push(t)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (let tag of tags) {
|
||||
// console.log('tag', tag)
|
||||
jsonAllData.tags.tagstore.tag.map(elem => {
|
||||
@ -103,29 +143,30 @@ function computeData(jsonAllData) {
|
||||
elem.tasksListByTitle.push(t.title)
|
||||
if (t['$'].status == "Active") {
|
||||
elem.tasksListIsActiveByTitle.push(t.title)
|
||||
|
||||
}
|
||||
if (t['$'].status == "Done") {
|
||||
elem.tasksListIsDoneByTitle.push(t.title)
|
||||
}
|
||||
}
|
||||
if(elem.tasks > jsonAllData.stats.maxTasksCountPerTag){
|
||||
if (elem.tasks > jsonAllData.stats.maxTasksCountPerTag) {
|
||||
jsonAllData.stats.maxTasksCountPerTag = elem.tasks
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
if (t.donedate) {
|
||||
jsonAllData.stats.tasksClosed++;
|
||||
jsonAllData.stats.listOpen.push(t);
|
||||
} else {
|
||||
jsonAllData.stats.tasksOpen++;
|
||||
}
|
||||
// console.log('tags', tags)
|
||||
}
|
||||
// sort tags by name
|
||||
|
||||
return jsonAllData
|
||||
|
||||
}
|
||||
|
||||
const oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
|
||||
function getNumberOfDaysDiffTwoDates(firstDate, secondDate) {
|
||||
return Math.round(Math.abs((firstDate - secondDate) / oneDay));
|
||||
}
|
||||
|
||||
function convertOneXmlToJson(fileToOpen, res) {
|
||||
fs.readFile(`sources/${fileToOpen}.xml`, "utf-8", function (err, data) {
|
||||
if (err) console.log(err);
|
||||
@ -146,40 +187,105 @@ function getPercent(someCount, total) {
|
||||
function computeBgColorOnProportionOfOpenTasks(someProportionNumber) {
|
||||
let result = '';
|
||||
|
||||
if(someProportionNumber >= 95){
|
||||
if (someProportionNumber >= 95) {
|
||||
result = 'proportion-over-95'
|
||||
}
|
||||
else if(someProportionNumber >= 90){
|
||||
} else if (someProportionNumber >= 90) {
|
||||
result = 'proportion-over-90'
|
||||
}
|
||||
else if(someProportionNumber >= 80){
|
||||
} else if (someProportionNumber >= 80) {
|
||||
result = 'proportion-over-80'
|
||||
}
|
||||
else if(someProportionNumber >= 65){
|
||||
} else if (someProportionNumber >= 65) {
|
||||
result = 'proportion-over-65'
|
||||
}
|
||||
else if(someProportionNumber >= 50){
|
||||
} else if (someProportionNumber >= 50) {
|
||||
result = 'proportion-over-50'
|
||||
}
|
||||
else if(someProportionNumber >= 40){
|
||||
} else if (someProportionNumber >= 40) {
|
||||
result = 'proportion-over-40'
|
||||
}
|
||||
else if(someProportionNumber >= 25){
|
||||
} else if (someProportionNumber >= 25) {
|
||||
result = 'proportion-over-25'
|
||||
}
|
||||
else if(someProportionNumber >= 15){
|
||||
} else if (someProportionNumber >= 15) {
|
||||
result = 'proportion-over-15'
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
let datenow = new Date();
|
||||
let dataTagsMd = `# Export de Tâches GTG \n date: ` + datenow.toLocaleString()
|
||||
|
||||
function exportToMarkdown(res) {
|
||||
|
||||
let datenow = new Date();
|
||||
let dataTagsMd = '# Export de Tags GTG du '+ datenow.toLocaleString();
|
||||
|
||||
// fichier de rapport des tâches fermées durant les 7 derniers jours
|
||||
dataTagsMd += `\n# Rapport hebdomadaire de dev `;
|
||||
dataTagsMd += `\n## ${jsonAllData.stats.listDevWeeklyClosed.length} ont été fermées `;
|
||||
jsonAllData.stats.listDevWeeklyClosed.map(elem => {
|
||||
dataTagsMd += `\n * ${elem.title}`;
|
||||
})
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n---`;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n# Rapport des tâches durant les 7 derniers jours `;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n## ${jsonAllData.stats.listClosedWeekly.length} ont été fermées `;
|
||||
dataTagsMd += `\n `;
|
||||
jsonAllData.stats.listClosedWeekly.map(elem => {
|
||||
dataTagsMd += `\n * ${elem.title}`;
|
||||
})
|
||||
dataTagsMd += `\n## ${jsonAllData.stats.listOpenWeekly.length} ont été ouvertes `;
|
||||
dataTagsMd += `\n `;
|
||||
jsonAllData.stats.listOpenWeekly.map(elem => {
|
||||
dataTagsMd += `\n * ${elem.title}`;
|
||||
})
|
||||
dataTagsMd += `\n--- `;
|
||||
// fichier de rapport des tâches fermées durant les 31 derniers jours
|
||||
dataTagsMd += `\n# Rapport des autres tâches durant le mois `;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n## ${jsonAllData.stats.listClosedWeekly.length} ont été fermées `;
|
||||
dataTagsMd += `\n `;
|
||||
|
||||
dataTagsMd += `\n## ${jsonAllData.stats.listOpenWeekly.length} ont été ouvertes `;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n--- `;
|
||||
// stats de fermeture des tâches
|
||||
dataTagsMd += `\n# Stats de fermeture des tâches `;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n--- `;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n# Export de toutes les ${jsonAllData.stats.listOpen.length} tâches ouvertes GTG \n `;
|
||||
dataTagsMd += `\n `;
|
||||
|
||||
// jsonAllData.stats.listOpen.map(elem => {
|
||||
// dataTagsMd += `\n## ${elem.title} `;
|
||||
// dataTagsMd += `\n statut : ${elem['$'].status} `;
|
||||
// dataTagsMd += `\n créé le : ${elem.addeddate} `;
|
||||
// dataTagsMd += `\n modifié le : ${elem.modified} `;
|
||||
// dataTagsMd += `\n prévu pour : ${elem.duedate | ''} `;
|
||||
// dataTagsMd += `\n ${elem.content} `;
|
||||
// })
|
||||
dataTagsMd += `\n--- `;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n# Export de toutes les ${jsonAllData.stats.listClosed.length} tâches fermées GTG \n `;
|
||||
dataTagsMd += `\n `;
|
||||
//
|
||||
// jsonAllData.stats.listClosed.map(elem=>{
|
||||
// dataTagsMd += `\n * ${elem.title} `;
|
||||
// })
|
||||
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n# Export de Tags GTG \n `;
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n `;
|
||||
|
||||
let sortedTagsByTitle = _.sortBy(jsonAllData.tags.tagstore.tag, [(o) => {
|
||||
o["$"].name
|
||||
}])
|
||||
|
||||
sortedTagsByTitle.map(elem => {
|
||||
dataTagsMd += `\n * ${elem['$'].name} , ${elem.tasks | 0}`;
|
||||
})
|
||||
|
||||
dataTagsMd += `\n `;
|
||||
dataTagsMd += `\n rapport généré avec gtg2nodejs par tykayn - contact@cipherbliss.com `;
|
||||
// write file to disk
|
||||
fs.writeFile('output/export_tags.md', dataTagsMd, 'utf8', (err) => {
|
||||
fs.writeFile(`output/export_tags.md`, dataTagsMd, `utf8`, (err) => {
|
||||
|
||||
if (err) {
|
||||
console.log(`Error writing file: ${err}`);
|
||||
|
@ -6,8 +6,12 @@ block content
|
||||
section.tasks
|
||||
h2 #{json.tasks.project.task.length} Tâches
|
||||
ul.stats
|
||||
li #{json.stats.tasksOpen} ouvertes
|
||||
li #{json.stats.tasksClosed} fermées
|
||||
li #{json.stats.listOpen.length} ouvertes
|
||||
li #{json.stats.listOpenWeekly.length} ouvertes cette semaine
|
||||
li #{json.stats.listOpenMonthly.length} ouvertes ce mois-ci
|
||||
li #{json.stats.listClosed.length} fermées
|
||||
li #{json.stats.listClosedWeekly.length} fermées cette semaine
|
||||
li #{json.stats.listClosedMonthly.length} fermées ce mois-ci
|
||||
section.tags
|
||||
h2 #{json.tags.tagstore.tag.length} Tags
|
||||
p maximum de #{json.stats.maxTasksCountPerTag} tâches pour un tag.
|
||||
|
Loading…
Reference in New Issue
Block a user