docs: guide d'utilisation enrichi + navigation clavier — sections Tabs, Édition, Graphe, Palette, Partage, Sauvegardes, Sécurité
This commit is contained in:
parent
34d89706be
commit
9f00455064
@ -79,7 +79,7 @@
|
||||
- Export dans la vue publique `/s/{token}/pdf` ✅
|
||||
- GTK/Pango installé dans le Dockerfile ✅
|
||||
|
||||
### ✅ 3. Palette de commandes (Ctrl+P) — FAIT
|
||||
### ✅ 3. Palette de commandes (Ctrl+ALT+SPACE) — FAIT
|
||||
- Navigation rapide fichiers + commandes (> prefix) ✅
|
||||
- Module `frontend/js/palette.js` + intégré dans app.js ✅
|
||||
|
||||
@ -107,6 +107,10 @@
|
||||
- **Effort** : 0.5 jour | **Impact** : 🟢
|
||||
- `indexer.py` et `watcher.py` ont des définitions séparées → mutualiser
|
||||
|
||||
### 10. Indicateur AI Actif
|
||||
- **Effort** : 0.5 jour | **Impact** : 🟡
|
||||
- Dans le bouton/indicateur à droite du titre, en cliquant il y a un panneau avec les statut de syncro. Ajouter un indicateur visuel dans ce panneau pour indiquer si l'IA est actif, configuré, et fonctionnelle. Durant la phase de traitement de l'IA, le bouton/indicateur devrait changer de couleur pour un blanc qui flashindiquant le statut de la tâche AI en cours.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Backlog (P3/P4 — Long terme)
|
||||
|
||||
@ -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>></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>
|
||||
|
||||
@ -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) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user