feat(notes): vues structurées tableau/kanban, flashcards et MCP robuste
Some checks failed
CI / Lint, Test & Build (push) Failing after 57s
CI / Deploy production (on server) (push) Has been skipped

Ajoute la base organisable par carnet (schéma, champs partagés, valeurs par note)
avec activation guidée, tableau éditable, kanban et suppression de colonnes.
Corrige le multiselect en vue tableau et enrichit sidebar, grille et i18n FR/EN.
Inclut aussi les améliorations flashcards SM-2, l'audit consentement IA et la
robustesse du serveur MCP (config, validation, rate-limit, métriques).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Antigravity
2026-05-24 23:03:16 +00:00
parent ecd7e57c2e
commit 0784c94242
63 changed files with 10133 additions and 619 deletions

View File

@@ -71,7 +71,10 @@
"sortManual": "Ordre libre",
"moveFailed": "Échec du déplacement du carnet",
"dropToRoot": "Déposez ici pour déplacer à la racine",
"noReminders": "Aucun rappel actif."
"noReminders": "Aucun rappel actif.",
"documents": "Documents",
"searchNotebooksPlaceholder": "Rechercher un carnet…",
"clearSearch": "Effacer la recherche"
},
"notes": {
"title": "Notes",
@@ -2414,6 +2417,7 @@
"confirmSave": "Enregistrer dans le deck",
"generateFailed": "Impossible de générer les flashcards",
"saveFailed": "Impossible d'enregistrer les flashcards",
"schemaMissing": "Les flashcards ne sont pas encore disponibles sur ce serveur (migration base de données en attente).",
"savedCount": "{count} flashcards enregistrées",
"cardCount": "Nombre de cartes",
"styleLabel": "Style de cartes",
@@ -2438,6 +2442,10 @@
"cardCountLabel": "{count} cartes",
"masteredShort": "maîtrisées",
"viewDeck": "Détails",
"hideDeck": "Masquer",
"deckCardsEmpty": "Ce deck ne contient aucune carte pour l'instant.",
"dueBadge": "À réviser",
"masteredBadge": "Maîtrisée",
"review": "Réviser",
"startReview": "Lancer la révision",
"activeDeck": "Deck actif",
@@ -2450,6 +2458,8 @@
"front": "Recto",
"back": "Verso",
"tapToFlip": "Espace ou clic pour retourner",
"gradeSelected": "Enregistré — {label}",
"ratePrompt": "À quel point aviez-vous mémorisé cette carte ?",
"grade": {
"hard": "Difficile (1)",
"difficult": "Dur (2)",
@@ -2463,8 +2473,161 @@
"heatmapTitle": "Activité de révision",
"heatmapLast90": "90 derniers jours",
"retentionRate": "Taux de rétention",
"retentionCurve": "Rétention hebdomadaire",
"difficultCards": "Cartes difficiles"
"masteredLabel": "{count}/{total} maîtrisées",
"retentionCurve": "Taux de succès hebdomadaire",
"retentionCurveHint": "Basé sur les révisions avec note ≥ Bien (3 ou 4)",
"retentionNoDataYet": "Révisez des cartes sur plusieurs semaines pour voir votre courbe de rétention.",
"streak": "Série en cours",
"streakDays": "j",
"totalReviewsLabel": "Révisions totales",
"totalCardsLabel": "Cartes au total",
"nextReviewLabel": "Prochain",
"dueToday": "Dû aujourd'hui",
"nextReviewIn": "Dans {days}j",
"difficultCards": "Cartes difficiles",
"notebookBadge": "Carnet",
"reviewMode": "Mode",
"reviewModeAll": "Toutes les cartes",
"reviewModeDue": "Cartes dues uniquement",
"sessionStats": "Bilan de session",
"sessionReviewed": "Cartes révisées",
"sessionNewMastered": "Nouvellement maîtrisées",
"sessionDuration": "Durée",
"editCard": "Modifier",
"deleteCard": "Supprimer la carte",
"deleteCardConfirm": "Supprimer cette carte définitivement ?",
"deleteDeck": "Supprimer le deck",
"deleteDeckConfirm": "Supprimer ce deck et toutes ses cartes définitivement ?",
"deckDeleted": "Deck supprimé",
"cardDeleted": "Carte supprimée",
"cardSaved": "Carte enregistrée",
"cardTypeBadge": "{type}",
"reviewNow": "Réviser maintenant",
"deleteFailed": "Impossible de supprimer"
},
"structuredViews": {
"enableTitle": "Organiser ce carnet (tableau, kanban, galerie…)",
"enableLabel": "Organiser",
"enabledHint": "Mode organisé activé",
"enabledHintDetail": "Vos champs apparaissent dans le panneau Info de chaque note.",
"enableFailed": "Impossible d'activer l'organisation",
"viewList": "Liste",
"viewTable": "Tableau",
"viewTableHint": "Tableau structuré — une ligne par note, une colonne par champ (statut, date…)",
"viewKanban": "Kanban",
"viewGallery": "Galerie",
"viewKanbanHint": "Colonnes — comme un tableau Trello pour faire avancer vos notes",
"viewGalleryHint": "Cartes visuelles — parcourir vos notes en un coup d'œil",
"intro": {
"databaseTitle": "Base organisable",
"databaseBody": "Ajoutez des champs partagés (Statut, Échéance, Priorité…) à chaque note de ce carnet. Le texte de vos notes ne change pas : ce sont des métadonnées communes, comme une mini base de données Notion.",
"tableTitle": "Vue tableau",
"tableBody": "Toutes vos notes en lignes, vos champs en colonnes. Modifiez statut ou date directement dans la grille.",
"kanbanTitle": "Vue Kanban",
"kanbanBody": "Les mêmes notes, en cartes réparties en colonnes (ex. À faire → En cours → Terminé). Glissez-déposez pour changer le statut.",
"activateTableHint": "Nous créons un champ « Statut » par défaut. Vous pourrez en ajouter d'autres avec le bouton +.",
"activateKanbanHint": "Nous créons un champ « Statut » avec trois colonnes. Vous pourrez renommer les options ou ajouter des champs ensuite.",
"enableTable": "Activer le tableau",
"enableKanban": "Activer le Kanban",
"enabling": "Activation…",
"enabledSuccess": "Base organisable activée pour ce carnet"
},
"helpBanner": {
"table": "Vue tableau : une ligne par note, une colonne par champ. Cliquez une cellule pour modifier. Survolez l'en-tête d'une colonne pour la supprimer (icône poubelle).",
"kanban": "Vue Kanban : faites glisser une carte pour changer son statut. Utilisez + dans une colonne pour créer une note déjà classée.",
"dismiss": "Compris"
},
"addPropertyTitle": "Ajouter un champ",
"addProperty": "Ajouter un champ",
"addPropertyHint": "La colonne apparaît sur toutes les notes du carnet, mais chaque note garde sa propre valeur (vide tant que vous ne l'avez pas remplie).",
"deleteProperty": "Supprimer le champ",
"deletePropertyTitle": "Supprimer ce champ ?",
"deletePropertyConfirm": "Le champ « {name} » et toutes ses valeurs sur les notes de ce carnet seront supprimés. Cette action est irréversible.",
"deletePropertySuccess": "Champ supprimé",
"cellEmpty": "—",
"multiselectPick": "Choisir…",
"propertyName": "Nom du champ",
"propertyType": "Type de donnée",
"selectOptions": "Options (une par ligne)",
"selectOptionsPlaceholder": "À faire\nEn cours\nTerminé",
"propertiesSection": "Champs du carnet",
"noPropertiesYet": "Aucun champ pour l'instant.",
"noFilter": "Sans filtre",
"filterContains": "Contient",
"filterEquals": "Est égal à",
"filterEmpty": "Est vide",
"filterValue": "Valeur du filtre…",
"noMatchingNotes": "Aucune note ne correspond à ce filtre.",
"kanbanGroupBy": "Regrouper par",
"kanbanUnassigned": "Non classé",
"kanbanAllNotes": "Toutes les notes",
"kanbanSingleColumnHint": "Vos notes sont ici. Pour avoir plusieurs colonnes (À faire, En cours, Terminé), un clic suffit.",
"kanbanAddStatusColumns": "Créer colonnes Statut",
"chooseGroupProperty": "Choisir le champ de regroupement",
"newNoteInColumn": "Nouvelle note",
"propertyTypes": {
"text": "Texte",
"number": "Nombre",
"date": "Date",
"select": "Liste de choix",
"multiselect": "Choix multiples",
"checkbox": "Case oui/non"
},
"wizard": {
"title": "Organiser ce carnet",
"subtitle": "Comme un petit tableur : des infos en plus sur chaque note, sans toucher au texte.",
"stepGoal": "À quoi sert ce carnet ?",
"stepFields": "Quels champs ajouter ?",
"stepView": "Comment afficher vos notes ?",
"fieldsHint": "Un champ = une colonne partagée (statut, date…). Vous pourrez le remplir note par note.",
"kanbanNeedsStatus": "Cochez un champ « liste de choix » (ex. Statut) pour utiliser le Kanban.",
"doneHint": "Vous pourrez remplir les champs plus tard — ou laisser vide.",
"back": "Retour",
"next": "Suivant",
"finish": "Terminer",
"readyToast": "C'est prêt — remplissez les champs quand vous voulez.",
"openFromKanban": "Configurer avec l'assistant",
"goals": {
"tasks": {
"title": "Suivre des tâches",
"desc": "Statut, échéance — idéal pour un Kanban."
},
"learning": {
"title": "Apprendre / réviser",
"desc": "Niveau, date de révision — idéal en galerie."
},
"reading": {
"title": "Lire et classer",
"desc": "Lu ou pas, source — pour articles et références."
},
"simple": {
"title": "Juste organiser",
"desc": "Changer de vue sans champs obligatoires."
}
},
"fields": {
"status": {
"name": "Statut",
"options": "À faire\nEn cours\nTerminé"
},
"dueDate": {
"name": "Échéance"
},
"level": {
"name": "Niveau",
"options": "Débutant\nIntermédiaire\nAvancé"
},
"lastReview": {
"name": "Dernière révision"
},
"read": {
"name": "Lu"
},
"source": {
"name": "Source"
}
}
}
},
"brainstorm": {
"title": "Vagues de pensée",
@@ -3152,4 +3315,4 @@
"uploadFailed": "Échec du téléchargement",
"uploading": "Téléchargement..."
}
}
}