docs: guide d'utilisation enrichi + navigation clavier — sections Tabs, Édition, Graphe, Palette, Partage, Sauvegardes, Sécurité
CI / lint (push) Failing after 7s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / security (push) Successful in 10s

This commit is contained in:
2026-06-02 15:25:08 -04:00
parent 34d89706be
commit 9f00455064
3 changed files with 282 additions and 17 deletions
+223 -15
View File
@@ -773,16 +773,23 @@
<nav class="help-nav" id="help-nav">
<div class="help-nav-title">Sommaire</div>
<ul class="help-nav-list">
<li><a href="#help-intro" class="help-nav-link">📘 Introduction</a></li>
<li><a href="#help-interface" class="help-nav-link">🧭 Interface</a></li>
<li><a href="#help-navigation" class="help-nav-link">🗺️ Navigation</a></li>
<li><a href="#help-recherche" class="help-nav-link">🔍 Recherche</a></li>
<li><a href="#help-tags" class="help-nav-link">🏷️ Tags</a></li>
<li><a href="#help-fichiers" class="help-nav-link">📁 Fichiers</a></li>
<li><a href="#help-personnalisation" class="help-nav-link">🎨 Personnalisation</a></li>
<li><a href="#help-raccourcis" class="help-nav-link">⌨️ Raccourcis</a></li>
<li><a href="#help-ai" class="help-nav-link">🤖 IA Éditeur</a></li>
<li><a href="#help-astuces" class="help-nav-link">💡 Astuces</a></li>
<li><a href="#help-intro" class="help-nav-link">📘 Introduction</a></li>
<li><a href="#help-interface" class="help-nav-link">🧭 Interface</a></li>
<li><a href="#help-navigation" class="help-nav-link">🗺️ Navigation</a></li>
<li><a href="#help-tabs" class="help-nav-link">📑 Onglets</a></li>
<li><a href="#help-recherche" class="help-nav-link">🔍 Recherche</a></li>
<li><a href="#help-tags" class="help-nav-link">🏷️ Tags</a></li>
<li><a href="#help-fichiers" class="help-nav-link">📁 Fichiers</a></li>
<li><a href="#help-edition" class="help-nav-link">✏️ Édition</a></li>
<li><a href="#help-graphe" class="help-nav-link">🗺️ Graphe</a></li>
<li><a href="#help-ia" class="help-nav-link">🤖 IA Éditeur</a></li>
<li><a href="#help-palette" class="help-nav-link">⌨️ Palette</a></li>
<li><a href="#help-raccourcis" class="help-nav-link">⌨️ Raccourcis</a></li>
<li><a href="#help-partage" class="help-nav-link">🔗 Partage</a></li>
<li><a href="#help-sauvegardes" class="help-nav-link">💾 Sauvegardes</a></li>
<li><a href="#help-securite" class="help-nav-link">🛡️ Sécurité</a></li>
<li><a href="#help-personnalisation" class="help-nav-link">🎨 Personnalisation</a></li>
<li><a href="#help-astuces" class="help-nav-link">💡 Astuces</a></li>
</ul>
</nav>
<div class="help-content">
@@ -891,6 +898,35 @@
</ul>
</section>
<section class="help-section" id="help-tabs">
<h2>📑 Gestion des onglets</h2>
<p>ObsiGate supporte l'ouverture de plusieurs fichiers simultanément dans des onglets.</p>
<h3>Ouverture d'onglets</h3>
<ul>
<li><strong>Simple clic</strong> : Ouvre le fichier dans un onglet temporaire (aperçu, italique)</li>
<li><strong>Double clic</strong> : Ouvre le fichier dans un onglet persistant</li>
<li><strong>Navigation récente</strong> : L'onglet "Récent" dans la sidebar liste vos derniers fichiers</li>
</ul>
<h3>Navigation entre onglets</h3>
<ul>
<li><strong>Clic sur un onglet</strong> : Active l'onglet</li>
<li><strong>Ctrl+Tab</strong> : Onglet suivant</li>
<li><strong>Ctrl+Shift+Tab</strong> : Onglet précédent</li>
<li><strong>Ctrl+W</strong> : Fermer l'onglet actif</li>
<li><strong>Bouton ✕</strong> : Ferme l'onglet (sauf s'il est seul)</li>
</ul>
<h3>Fonctionnalités</h3>
<ul>
<li><strong>Barre d'onglets</strong> : Affichage horizontal avec le nom du fichier et son icône</li>
<li><strong>Onglet actif</strong> : Surligné en couleur d'accentuation</li>
<li><strong>Prévisualisation</strong> : Un onglet temporaire (italique) est remplacé par le prochain clic</li>
<li><strong>Onglets persistants</strong> : Restent ouverts jusqu'à fermeture manuelle</li>
</ul>
</section>
<section class="help-section" id="help-recherche">
<h2>🔍 Recherche</h2>
@@ -1017,6 +1053,59 @@
</ul>
</section>
<!-- ✏️ Édition -->
<section class="help-section" id="help-edition">
<h2>✏️ Édition avancée</h2>
<h3>Éditeur CodeMirror 6</h3>
<p>L'éditeur intégré offre une expérience complète d'édition :</p>
<ul>
<li><strong>Coloration syntaxique</strong> : Python, JS, HTML, CSS, Java, C++, Rust, Go et bien d'autres</li>
<li><strong>Numéros de ligne</strong> : Navigation facilitée dans les fichiers longs</li>
<li><strong>Find in page</strong> : Ctrl+F pour chercher dans le fichier (casse, regex, mot entier)</li>
<li><strong>Sauvegarde automatique</strong> : Auto-save silencieux après 2s d'inactivité, flash vert de confirmation</li>
<li><strong>Bouton ✓</strong> : Sauvegarde manuelle</li>
<li><strong>Bouton 🗑️</strong> : Suppression du fichier</li>
<li><strong>Barre d'outils AI</strong> : Complétion, réécriture, traduction (voir section <a href="#help-ia">IA</a>)</li>
</ul>
</section>
<!-- 🗺️ Graphe -->
<section class="help-section" id="help-graphe">
<h2>🗺️ Vue Graphe</h2>
<p>La vue graphe offre une visualisation interactive des connexions entre vos notes via les wikilinks.</p>
<h3>Ouverture</h3>
<ul>
<li><strong>Menu contextuel</strong> : Clic droit sur un vault ou dossier → Vue Graphique</li>
<li><strong>Bouton dédié</strong> : Dans la barre d'outils (le cas échéant)</li>
</ul>
<h3>Interaction</h3>
<ul>
<li><strong>Zoom/Pan</strong> : Molette pour zoomer, cliquer-glisser pour se déplacer</li>
<li><strong>Slider de profondeur</strong> : Contrôle la profondeur d'exploration (0-3)</li>
<li><strong>Filtre par tag</strong> : N'affiche que les nœuds avec un tag spécifique</li>
<li><strong>Filtre par type</strong> : Inclut/exclut fichiers, dossiers, markdown, autres</li>
<li><strong>Recherche visuelle</strong> : Barre de recherche pour surligner des nœuds</li>
<li><strong>Mode focus</strong> : Centre la vue sur un nœud spécifique</li>
<li><strong>Navigation ← → ↑</strong> : Historique de navigation entre les nœuds</li>
</ul>
<h3>Affichage</h3>
<ul>
<li><strong>Nœuds</strong> : Fichiers (carrés) et dossiers (cercles) avec icônes</li>
<li><strong>Arêtes</strong> : Wikilinks sortants (bleu) et backlinks entrants (vert)</li>
<li><strong>Panneau d'info</strong> : Métadonnées du nœud (tags, liens, chemin)</li>
<li><strong>Ctrl+survol</strong> : Aperçu du contenu de la note sans naviguer</li>
<li><strong>Plein écran</strong> : Bouton pour agrandir la vue</li>
<li><strong>Export PNG</strong> : Sauvegardez le graphe en image</li>
</ul>
<h3>Performance</h3>
<p>La vue utilise l'algorithme Barnes-Hut pour calculer la disposition en O(n log n), garantissant des performances fluides même avec des centaines de nœuds.</p>
</section>
<section class="help-section" id="help-personnalisation">
<h2>🎨 Personnalisation</h2>
@@ -1049,8 +1138,48 @@
</ul>
</section>
<section class="help-section" id="help-raccourcis">
<h2>⌨️ Raccourcis clavier</h2>
<!-- ⌨️ Palette de commandes -->
<section class="help-section" id="help-palette">
<h2>⌨️ Palette de commandes</h2>
<p>La palette de commandes permet d'accéder rapidement aux fichiers et aux actions sans utiliser la souris.</p>
<h3>Ouverture</h3>
<ul>
<li><strong>Ctrl+Shift+Espace</strong> : Palette de fichiers (recherche par titre)</li>
<li><strong>Ctrl+Alt+Espace</strong> : Palette de commandes (liste d'actions)</li>
<li><strong>Tab</strong> : Bascule entre mode fichiers et mode commandes</li>
</ul>
<h3>Mode fichiers</h3>
<p>Tapez le nom d'un fichier pour le trouver rapidement. La recherche utilise l'API <code>/api/suggest</code> pour des suggestions instantanées. Appuyez sur <kbd>Enter</kbd> pour ouvrir le fichier sélectionné.</p>
<h3>Mode commandes</h3>
<p>Tapez <code>&gt;</code> (ou Ctrl+Alt+Espace) pour voir la liste des actions disponibles :</p>
<ul>
<li>🏠 <strong>Accueil</strong> : Retour à l'accueil</li>
<li>✏️ <strong>Éditer fichier courant</strong> : Ouvre l'éditeur sur l'onglet actif</li>
<li>🪟 <strong>Pop-out</strong> : Ouvre le document dans une fenêtre détachée</li>
<li>📄 <strong>Créer fichier markdown</strong> : Crée un nouveau fichier .md et l'ouvre dans l'éditeur</li>
<li>🗑️ <strong>Supprimer fichier courant</strong> : Supprime le fichier de l'onglet actif</li>
<li>📁 <strong>Créer répertoire</strong> : Crée un nouveau dossier</li>
<li>🗑️ <strong>Supprimer répertoire</strong> : Supprime un dossier et son contenu</li>
<li>🌓 <strong>Changer le thème</strong> : Bascule clair/sombre</li>
<li>🔄 <strong>Réindexer</strong> : Force la réindexation complète</li>
<li>❓ <strong>Aide</strong> : Ouvre ce guide</li>
<li>⚙️ <strong>Configuration</strong> : Ouvre les paramètres</li>
</ul>
<h3>Navigation</h3>
<ul>
<li><kbd>↑</kbd> <kbd>↓</kbd> : Se déplacer dans la liste</li>
<li><kbd>Enter</kbd> : Ouvrir/sélectionner</li>
<li><kbd>Esc</kbd> : Fermer la palette</li>
<li><kbd>Tab</kbd> : Basculer entre fichiers et commandes</li>
</ul>
</section>
<section class="help-section" id="help-raccourcis">
<h2>⌨️ Raccourcis clavier</h2>
<h3>Navigation</h3>
<ul>
@@ -1069,6 +1198,16 @@
<h3>Interface</h3>
<ul>
<li><code>Ctrl+T</code> : Basculer le thème clair/sombre</li>
<li><code>Ctrl+Shift+Espace</code> : Palette de fichiers</li>
<li><code>Ctrl+Alt+Espace</code> : Palette de commandes</li>
<li><code>Escape</code> : Fermer la palette / les suggestions</li>
</ul>
<h3>Onglets</h3>
<ul>
<li><code>Ctrl+W</code> : Fermer l'onglet actif</li>
<li><code>Ctrl+Tab</code> : Onglet suivant</li>
<li><code>Ctrl+Shift+Tab</code> : Onglet précédent</li>
</ul>
<h3>Éditeur CodeMirror</h3>
@@ -1154,8 +1293,77 @@
<p>Pour changer de provider par défaut : <code>AI_DEFAULT_PROVIDER=openrouter</code></p>
</section>
<section class="help-section" id="help-astuces">
<h2>💡 Astuces et bonnes pratiques</h2>
<!-- 🔗 Partage -->
<section class="help-section" id="help-partage">
<h2>🔗 Partage et Webhooks</h2>
<h3>Publication publique</h3>
<p>ObsiGate permet de partager des documents via un lien public temporaire.</p>
<ul>
<li><strong>Bouton Partager</strong> : Dans les actions du fichier, génère un lien unique</li>
<li><strong>Token unique</strong> : 64 caractères hexadécimaux, impossible à deviner</li>
<li><strong>Expiration configurable</strong> : Durée de vie en heures</li>
<li><strong>Lecture seule</strong> : La vue publique n'affiche que le contenu sans édition</li>
<li><strong>Gestion des liens</strong> : Liste et révocation dans les Configurations</li>
<li><strong>Export PDF</strong> : Téléchargement du document partagé en PDF via <code>/s/{token}/pdf</code></li>
</ul>
<h3>Webhooks</h3>
<p>Les webhooks notifient des services externes lors des changements de fichiers.</p>
<ul>
<li><strong>Événements</strong> : Création, modification, suppression, renommage</li>
<li><strong>Format</strong> : POST JSON avec détails complets de l'événement</li>
<li><strong>Signature HMAC-SHA256</strong> : Optionnelle pour vérifier l'origine</li>
<li><strong>Configuration</strong> : Gestion via le modal Configurations</li>
</ul>
</section>
<!-- 💾 Sauvegardes -->
<section class="help-section" id="help-sauvegardes">
<h2>💾 Sauvegardes et Audits</h2>
<h3>Backup automatique</h3>
<p>ObsiGate crée automatiquement des sauvegardes avant chaque modification destructive.</p>
<ul>
<li><strong>Avant écriture</strong> : Sauvegarde du contenu original dans <code>.obsigate-backup/</code></li>
<li><strong>Timestamp</strong> : Chaque backup est horodaté</li>
<li><strong>Répertoire dédié</strong> : <code>.obsigate-backup/</code> dans le répertoire de la vault</li>
</ul>
<h3>Audit log</h3>
<p>Toutes les opérations sensibles sont tracées dans un journal.</p>
<ul>
<li><strong>Journal</strong> : Fichier <code>data/audit.log</code> au format JSON lines</li>
<li><strong>Événements tracés</strong> : Écritures, suppressions, changements de configuration</li>
<li><strong>Rotation</strong> : Rotation automatique à 10 Mo</li>
</ul>
</section>
<!-- 🛡️ Sécurité -->
<section class="help-section" id="help-securite">
<h2>🛡️ Sécurité</h2>
<h3>Authentification</h3>
<ul>
<li><strong>JWT + Argon2id</strong> : Tokens JWT avec mots de passe hachés Argon2id</li>
<li><strong>Contrôle d'accès par vault</strong> : Chaque utilisateur voit uniquement ses vaults</li>
<li><strong>Refresh tokens</strong> : Cookies HttpOnly avec rotation automatique</li>
<li><strong>Rate limiting</strong> : 10 tentatives / 15 min par IP + verrouillage compte</li>
<li><strong>Compte admin</strong> : Créé automatiquement au premier démarrage</li>
</ul>
<h3>Protection</h3>
<ul>
<li><strong>Secret redactor</strong> : Masque JWT, clés API, tokens GitHub dans les aperçus</li>
<li><strong>Path traversal</strong> : Validation des chemins contre les attaques <code>../</code></li>
<li><strong>Headers CSP</strong> : Content-Security-Policy, X-Frame-Options, XSS-Protection</li>
<li><strong>Atomic writes</strong> : Écriture via fichier temporaire + renommage atomique</li>
<li><strong>Non-root Docker</strong> : Conteneur tourne avec UID 1000</li>
</ul>
</section>
<section class="help-section" id="help-astuces">
<h2>💡 Astuces et bonnes pratiques</h2>
<h3>Workflow recommandé</h3>
<ol>
@@ -1195,7 +1403,7 @@
</section>
<div class="help-footer">
<p><strong>ObsiGate v1.2.0</strong> - Porte d'entrée web pour vos vaults Obsidian</p>
<p><strong>ObsiGate v1.7.0</strong> - Porte d'entrée web pour vos vaults Obsidian</p>
<p>Pour plus d'informations, consultez le <a href="https://git.dracodev.net/Projets/ObsiGate" target="_blank">dépôt du projet</a>.</p>
</div>
</div>
+54 -1
View File
@@ -214,6 +214,7 @@ function initHelpNavigation() {
const helpContent = document.querySelector(".help-content");
const helpBody = document.getElementById("help-body");
const navLinks = document.querySelectorAll(".help-nav-link");
const navList = document.querySelector(".help-nav-list");
if (!helpContent || !helpBody || !navLinks.length) return;
@@ -225,11 +226,63 @@ function initHelpNavigation() {
const targetSection = document.getElementById(targetId);
if (targetSection) {
targetSection.scrollIntoView({ behavior: "smooth", block: "start" });
// Focus the section for accessibility
targetSection.setAttribute("tabindex", "-1");
targetSection.focus({ preventScroll: true });
}
});
});
// Scroll spy - update active nav link based on scroll position
// ── Keyboard navigation inside nav list ──
if (navList) {
navList.addEventListener("keydown", (e) => {
const items = [...navList.querySelectorAll(".help-nav-link")];
const currentIdx = items.indexOf(document.activeElement);
if (e.key === "ArrowDown" || e.key === "ArrowRight") {
e.preventDefault();
const next = (currentIdx + 1) % items.length;
items[next].focus();
} else if (e.key === "ArrowUp" || e.key === "ArrowLeft") {
e.preventDefault();
const prev = (currentIdx - 1 + items.length) % items.length;
items[prev].focus();
} else if (e.key === "Home") {
e.preventDefault();
items[0].focus();
} else if (e.key === "End") {
e.preventDefault();
items[items.length - 1].focus();
}
});
// Make nav items focusable
navList.querySelectorAll("li").forEach((li) => {
li.setAttribute("role", "none"); // remove listitem role for cleaner a11y
});
}
// ── Keyboard: Ctrl+↑/↓ inside help body to jump between sections ──
helpBody.addEventListener("keydown", (e) => {
if ((e.ctrlKey || e.metaKey) && (e.key === "ArrowDown" || e.key === "ArrowUp")) {
e.preventDefault();
const sections = [...document.querySelectorAll(".help-section")];
const currentSection = sections.find((s) => {
const rect = s.getBoundingClientRect();
return rect.top >= 0 && rect.top < 100;
});
if (!currentSection) return;
const currentIdx = sections.indexOf(currentSection);
if (e.key === "ArrowDown" && currentIdx < sections.length - 1) {
sections[currentIdx + 1].scrollIntoView({ behavior: "smooth", block: "start" });
} else if (e.key === "ArrowUp" && currentIdx > 0) {
sections[currentIdx - 1].scrollIntoView({ behavior: "smooth", block: "start" });
}
}
});
// ── Scroll spy ──
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {