ObsiGate/frontend/index.html

834 lines
44 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="fr" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ObsiGate</title>
<link rel="stylesheet" href="/static/style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css" id="hljs-theme-dark">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css" id="hljs-theme-light" disabled>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script src="https://unpkg.com/lucide@0.344.0/dist/umd/lucide.min.js"></script>
<script type="importmap">
{
"imports": {
"@codemirror/state": "https://esm.sh/@codemirror/state@6.2.0"
}
}
</script>
<!-- CodeMirror 6 -->
<script type="module">
import { EditorView, keymap, lineNumbers, highlightActiveLineGutter, highlightSpecialChars, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightActiveLine } from "https://esm.sh/@codemirror/view@6.9.0?external=@codemirror/state";
import { EditorState } from "@codemirror/state";
import { defaultHighlightStyle, syntaxHighlighting, indentOnInput, bracketMatching, foldGutter, foldKeymap } from "https://esm.sh/@codemirror/language@6.6.0?external=@codemirror/state";
import { defaultKeymap, history, historyKeymap } from "https://esm.sh/@codemirror/commands@6.2.3?external=@codemirror/state";
import { searchKeymap, highlightSelectionMatches } from "https://esm.sh/@codemirror/search@6.3.0?external=@codemirror/state";
import { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap } from "https://esm.sh/@codemirror/autocomplete@6.5.0?external=@codemirror/state";
import { markdown } from "https://esm.sh/@codemirror/lang-markdown@6.1.0?external=@codemirror/state";
import { python } from "https://esm.sh/@codemirror/lang-python@6.1.3?external=@codemirror/state";
import { javascript } from "https://esm.sh/@codemirror/lang-javascript@6.1.7?external=@codemirror/state";
import { html } from "https://esm.sh/@codemirror/lang-html@6.4.3?external=@codemirror/state";
import { css } from "https://esm.sh/@codemirror/lang-css@6.2.0?external=@codemirror/state";
import { json } from "https://esm.sh/@codemirror/lang-json@6.0.1?external=@codemirror/state";
import { xml } from "https://esm.sh/@codemirror/lang-xml@6.0.2?external=@codemirror/state";
import { sql } from "https://esm.sh/@codemirror/lang-sql@6.5.0?external=@codemirror/state";
import { php } from "https://esm.sh/@codemirror/lang-php@6.0.1?external=@codemirror/state";
import { cpp } from "https://esm.sh/@codemirror/lang-cpp@6.0.2?external=@codemirror/state";
import { java } from "https://esm.sh/@codemirror/lang-java@6.0.1?external=@codemirror/state";
import { rust } from "https://esm.sh/@codemirror/lang-rust@6.0.1?external=@codemirror/state";
import { oneDark } from "https://esm.sh/@codemirror/theme-one-dark@6.1.0?external=@codemirror/state";
const basicSetup = [
lineNumbers(),
highlightActiveLineGutter(),
highlightSpecialChars(),
history(),
foldGutter(),
drawSelection(),
dropCursor(),
EditorState.allowMultipleSelections.of(true),
indentOnInput(),
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
bracketMatching(),
closeBrackets(),
autocompletion(),
rectangularSelection(),
crosshairCursor(),
highlightActiveLine(),
highlightSelectionMatches(),
keymap.of([
...closeBracketsKeymap,
...defaultKeymap,
...searchKeymap,
...historyKeymap,
...foldKeymap,
...completionKeymap,
])
];
window.CodeMirror = { EditorView, EditorState, basicSetup, markdown, python, javascript, html, css, json, xml, sql, php, cpp, java, rust, oneDark, keymap };
</script>
</head>
<body>
<div class="search-progress-bar" id="search-progress-bar"><div class="search-progress-bar__fill"></div></div>
<!-- Login Screen (hidden by default, shown when auth is required) -->
<div id="login-screen" class="login-screen hidden">
<div class="login-card">
<div class="login-header">
<div class="login-logo">
<span class="login-logo-icon">📖</span>
<span class="login-logo-text">ObsiGate</span>
</div>
<p class="login-subtitle">Accès sécurisé à vos vaults</p>
</div>
<form id="login-form" class="login-form" autocomplete="on">
<div class="form-group">
<label for="login-username">Nom d'utilisateur</label>
<input type="text" id="login-username" name="username" autocomplete="username" placeholder="utilisateur" required autofocus />
</div>
<div class="form-group">
<label for="login-password">Mot de passe</label>
<div class="password-input-wrapper">
<input type="password" id="login-password" name="password" autocomplete="current-password" placeholder="••••••••" required />
<button type="button" id="toggle-password" class="password-toggle" aria-label="Afficher le mot de passe">👁</button>
</div>
</div>
<div class="form-group form-group--inline">
<label class="checkbox-label">
<input type="checkbox" id="remember-me" name="remember_me" />
<span>Se souvenir de moi (30 jours)</span>
</label>
</div>
<div id="login-error" class="login-error hidden"></div>
<button type="submit" id="login-btn" class="btn-login">
<span class="btn-text">Se connecter</span>
<span class="btn-spinner hidden"></span>
</button>
</form>
</div>
</div>
<!-- Main Application (wrapped for show/hide) -->
<div id="app" class="app-container">
<!-- Header -->
<header class="header">
<div class="header-left">
<button class="hamburger-btn" id="hamburger-btn" title="Menu">
<i data-lucide="menu" style="width:20px;height:20px"></i>
</button>
<button class="sidebar-toggle-btn" id="sidebar-toggle-btn" title="Afficher/Masquer la sidebar">
<i data-lucide="sidebar" style="width:20px;height:20px"></i>
</button>
<div class="header-logo" id="header-logo">
<i data-lucide="book-open" style="width:20px;height:20px"></i>
ObsiGate
</div>
<span class="sync-badge sync-badge--disconnected" id="sync-badge" title="Synchronisation"></span>
</div>
<div class="header-center">
<div class="search-wrapper">
<i data-lucide="search" class="search-icon" style="width:16px;height:16px"></i>
<div class="search-input-wrapper">
<input type="text" id="search-input" placeholder="Recherche..." autocomplete="off">
<div class="search-actions">
<button class="search-btn" id="search-case-btn" type="button" title="Respecter la casse" aria-label="Respecter la casse">
<span>Aa</span>
</button>
<button class="search-btn" id="search-clear-btn" type="button" title="Effacer la recherche" aria-label="Effacer la recherche">
<i data-lucide="x" style="width:14px;height:14px"></i>
</button>
</div>
</div>
<!-- Advanced search autocomplete dropdown -->
<div class="search-dropdown" id="search-dropdown" role="listbox" aria-label="Suggestions de recherche" hidden>
<div class="search-dropdown__section search-dropdown__section--history" id="search-dropdown-history">
<div class="search-dropdown__section-header">
<span>Historique</span>
<button class="search-dropdown__clear-btn" id="search-dropdown-clear-history" type="button" title="Effacer l'historique">
<i data-lucide="trash-2" style="width:12px;height:12px"></i>
</button>
</div>
<ul class="search-dropdown__list" id="search-dropdown-history-list"></ul>
</div>
<div class="search-dropdown__section search-dropdown__section--titles" id="search-dropdown-titles">
<div class="search-dropdown__section-header"><span>Fichiers</span></div>
<ul class="search-dropdown__list" id="search-dropdown-titles-list"></ul>
</div>
<div class="search-dropdown__section search-dropdown__section--tags" id="search-dropdown-tags">
<div class="search-dropdown__section-header"><span>Tags</span></div>
<ul class="search-dropdown__list" id="search-dropdown-tags-list"></ul>
</div>
<div class="search-dropdown__empty" id="search-dropdown-empty" hidden>
Aucune suggestion
</div>
</div>
<!-- Active search filter chips -->
<div class="search-chips" id="search-chips" hidden></div>
</div>
</div>
<div class="header-right">
<div class="vault-context-indicator" id="vault-context-indicator" title="Contexte vault actif">
<i data-lucide="database" style="width:14px;height:14px"></i>
<span id="vault-context-text">All</span>
</div>
<!-- User menu (visible when logged in) -->
<div class="user-menu" id="user-menu"></div>
<div class="header-menu">
<button class="header-menu-btn" id="header-menu-btn" title="Options">
<i data-lucide="settings" style="width:18px;height:18px"></i>
</button>
<div class="header-menu-dropdown" id="header-menu-dropdown">
<div class="menu-list" role="menu" aria-label="Options">
<label class="menu-list-row menu-list-select-row" for="vault-filter">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="folders" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Vault</span>
<div class="custom-dropdown" id="vault-filter-dropdown">
<button class="custom-dropdown-trigger" type="button" aria-haspopup="listbox" aria-expanded="false">
<span class="custom-dropdown-selected">Tous les vaults</span>
<i data-lucide="chevron-down" style="width:14px;height:14px"></i>
</button>
<ul class="custom-dropdown-menu" role="listbox" id="vault-filter-options">
<li role="option" data-value="all" class="custom-dropdown-option selected">Tous les vaults</li>
</ul>
<input type="hidden" id="vault-filter" value="all">
</div>
</span>
</label>
<button class="menu-list-row menu-list-button" id="theme-toggle" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="sun" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Thème</span>
<span class="menu-list-subtitle" id="theme-label">Clair</span>
</span>
</button>
<button class="menu-list-row menu-list-button" id="config-open-btn" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="settings" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Configurations</span>
<span class="menu-list-subtitle">Paramètres de l'application</span>
</span>
</button>
<button class="menu-list-row menu-list-button" id="help-open-btn" type="button" role="menuitem">
<span class="menu-list-icon" aria-hidden="true">
<i data-lucide="book-open" style="width:17px;height:17px"></i>
</span>
<span class="menu-list-content">
<span class="menu-list-title">Guide d'utilisation</span>
<span class="menu-list-subtitle">Ouvrir l'aide</span>
</span>
</button>
</div>
</div>
</div>
</div>
</header>
<!-- Main -->
<div class="main-body">
<!-- Mobile overlay -->
<div class="sidebar-overlay" id="sidebar-overlay"></div>
<!-- Sidebar -->
<aside class="sidebar" id="sidebar" role="navigation" aria-label="Navigation des vaults">
<!-- Sidebar filter -->
<div class="sidebar-filter">
<div class="sidebar-filter-input-wrapper">
<i data-lucide="filter" class="sidebar-filter-icon" style="width:14px;height:14px"></i>
<input type="text" id="sidebar-filter-input" placeholder="Filtrer fichiers..." autocomplete="off">
<div class="sidebar-filter-actions">
<button class="sidebar-filter-btn" id="sidebar-filter-case-btn" type="button" title="Respecter la casse" aria-label="Respecter la casse">
<span>Aa</span>
</button>
<button class="sidebar-filter-btn" id="sidebar-filter-clear-btn" type="button" title="Effacer le filtrage" aria-label="Effacer le filtrage">
<i data-lucide="x" style="width:14px;height:14px"></i>
</button>
</div>
</div>
</div>
<!-- Tab bar -->
<div class="sidebar-tabs" role="tablist" aria-label="Sections sidebar">
<button class="sidebar-tab active" id="sidebar-tab-vaults" role="tab"
aria-selected="true" aria-controls="sidebar-panel-vaults" data-tab="vaults">
<i data-lucide="folder-tree" style="width:13px;height:13px"></i>
<span>Vaults</span>
</button>
<button class="sidebar-tab" id="sidebar-tab-tags" role="tab"
aria-selected="false" aria-controls="sidebar-panel-tags" data-tab="tags">
<i data-lucide="tag" style="width:13px;height:13px"></i>
<span>Tags</span>
</button>
</div>
<!-- Vaults panel -->
<div class="sidebar-tab-panel active" id="sidebar-panel-vaults" role="tabpanel" aria-labelledby="sidebar-tab-vaults">
<div class="custom-dropdown sidebar-dropdown" id="vault-quick-select-dropdown">
<button class="custom-dropdown-trigger" type="button" aria-haspopup="listbox" aria-expanded="false">
<span class="custom-dropdown-selected">Tous les vaults</span>
<i data-lucide="chevron-down" style="width:14px;height:14px"></i>
</button>
<ul class="custom-dropdown-menu" role="listbox" id="vault-quick-select-options">
<li role="option" data-value="all" class="custom-dropdown-option selected">Tous les vaults</li>
</ul>
<input type="hidden" id="vault-quick-select" value="all">
</div>
<div id="vault-tree" role="tree" aria-label="Arborescence des fichiers"></div>
</div>
<!-- Tags panel -->
<div class="sidebar-tab-panel" id="sidebar-panel-tags" role="tabpanel" aria-labelledby="sidebar-tab-tags">
<div class="tag-cloud" id="tag-cloud"></div>
</div>
</aside>
<!-- Sidebar resize handle -->
<div class="sidebar-resize-handle" id="sidebar-resize-handle"></div>
<!-- Content -->
<main class="content-area" id="content-area" aria-label="Contenu principal">
<div class="welcome" id="welcome" role="status">
<i data-lucide="library" style="width:48px;height:48px;color:var(--text-muted)"></i>
<h2>ObsiGate</h2>
<p>Sélectionnez un fichier dans la sidebar ou utilisez la recherche pour commencer.</p>
</div>
</main>
</div>
</div>
<!-- Editor Modal -->
<div class="editor-modal" id="editor-modal">
<div class="editor-container">
<div class="editor-header">
<div class="editor-title" id="editor-title">Édition</div>
<div class="editor-actions">
<button class="editor-btn danger" id="editor-delete" title="Supprimer" aria-label="Supprimer">
<i data-lucide="trash-2" style="width:16px;height:16px"></i>
</button>
<button class="editor-btn" id="editor-cancel" title="Annuler" aria-label="Annuler">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
<button class="editor-btn primary" id="editor-save" title="Sauvegarder" aria-label="Sauvegarder">
<i data-lucide="check" style="width:16px;height:16px"></i>
</button>
</div>
</div>
<div class="editor-body" id="editor-body"></div>
</div>
</div>
<!-- Configurations Modal -->
<div class="editor-modal" id="config-modal">
<div class="editor-container">
<div class="editor-header">
<div class="editor-title">Configurations</div>
<div class="editor-actions">
<button class="editor-btn" id="config-close" title="Fermer" aria-label="Fermer">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
</div>
</div>
<div class="editor-body" id="config-body">
<div class="config-content">
<!-- Performance Settings — Frontend -->
<section class="config-section">
<h2>Paramètres de recherche</h2>
<p class="config-description">Ces paramètres s'appliquent immédiatement côté client.</p>
<div class="config-row">
<label class="config-label" for="cfg-debounce">Délai debounce (ms)</label>
<input type="number" id="cfg-debounce" class="config-input config-input--num" min="100" max="2000" step="50" value="300">
<span class="config-hint">Délai avant exécution de la recherche (1002000)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-results-per-page">Résultats par page</label>
<input type="number" id="cfg-results-per-page" class="config-input config-input--num" min="10" max="200" step="10" value="50">
<span class="config-hint">Nombre de résultats affichés par page (10200)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-min-query">Longueur min. requête</label>
<input type="number" id="cfg-min-query" class="config-input config-input--num" min="1" max="5" step="1" value="2">
<span class="config-hint">Nombre minimum de caractères avant recherche (15)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-timeout">Timeout recherche (ms)</label>
<input type="number" id="cfg-timeout" class="config-input config-input--num" min="5000" max="120000" step="5000" value="30000">
<span class="config-hint">Annuler la recherche après ce délai (5000120000)</span>
</div>
</section>
<!-- Performance Settings — Backend -->
<section class="config-section">
<h2>Paramètres backend <span class="config-badge-restart">Redémarrage requis</span></h2>
<p class="config-description">Ces paramètres sont sauvegardés sur le serveur. Certains nécessitent un redémarrage ou une réindexation.</p>
<div class="config-row">
<label class="config-label" for="cfg-workers">Workers de recherche</label>
<input type="number" id="cfg-workers" class="config-input config-input--num" min="1" max="8" step="1" value="2">
<span class="config-hint">Threads dédiés à la recherche (18)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-max-content">Taille max contenu (octets)</label>
<input type="number" id="cfg-max-content" class="config-input config-input--num" min="10000" max="1000000" step="10000" value="100000">
<span class="config-hint">Contenu indexé par fichier (10K1M). Réindexation requise.</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-title-boost">Boost titre</label>
<input type="number" id="cfg-title-boost" class="config-input config-input--num" min="0" max="10" step="0.5" value="3.0">
<span class="config-hint">Multiplicateur de pertinence pour les correspondances dans le titre</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-tag-boost">Boost tags</label>
<input type="number" id="cfg-tag-boost" class="config-input config-input--num" min="0" max="10" step="0.5" value="2.0">
<span class="config-hint">Multiplicateur de pertinence pour les correspondances dans les tags</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-prefix-exp">Expansions préfixe max</label>
<input type="number" id="cfg-prefix-exp" class="config-input config-input--num" min="10" max="200" step="10" value="50">
<span class="config-hint">Nombre max de tokens élargis par préfixe (10200)</span>
</div>
<div class="config-actions-row">
<button class="config-btn-save" id="cfg-save-backend">Sauvegarder</button>
<button class="config-btn-secondary" id="cfg-reindex">Forcer réindexation</button>
<button class="config-btn-secondary" id="cfg-reset-defaults">Réinitialiser</button>
</div>
</section>
<!-- Tag Filtering (existing) -->
<section class="config-section">
<h2>Filtrage de tags</h2>
<p class="config-description">Définissez les patterns de tags à masquer dans la sidebar. Vous pouvez utiliser des wildcards pour cibler les tags de template.</p>
<div class="config-filters-list" id="config-filters-list"></div>
<div class="config-add-pattern">
<input type="text" id="config-pattern-input" placeholder="Ex: #&lt;% ... %&gt; ou #{{ ... }}" class="config-input">
<button id="config-add-btn" class="config-btn-add">Ajouter</button>
</div>
<div class="config-regex-preview" id="config-regex-preview" style="display:none;">
<small>Regex : <code id="config-regex-code"></code></small>
</div>
</section>
<!-- Watcher / Synchronisation -->
<section class="config-section">
<h2>Synchronisation automatique</h2>
<p class="config-description">Surveillance des fichiers en temps réel via watchdog. Les modifications sont détectées automatiquement et l'index est mis à jour sans redémarrage.</p>
<div class="config-row">
<label class="config-label" for="cfg-watcher-enabled">Activer la surveillance</label>
<label class="config-toggle">
<input type="checkbox" id="cfg-watcher-enabled" checked>
<span class="config-toggle-slider"></span>
</label>
<span class="config-hint">Activer/désactiver la surveillance automatique des fichiers</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-watcher-polling">Mode polling (fallback)</label>
<label class="config-toggle">
<input type="checkbox" id="cfg-watcher-polling">
<span class="config-toggle-slider"></span>
</label>
<span class="config-hint">Forcer le mode polling au lieu de inotify natif (utile si le mode natif ne fonctionne pas)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-watcher-interval">Intervalle polling (s)</label>
<input type="number" id="cfg-watcher-interval" class="config-input config-input--num" min="1" max="30" step="1" value="5">
<span class="config-hint">Intervalle de scrutation en mode polling (130 secondes)</span>
</div>
<div class="config-row">
<label class="config-label" for="cfg-watcher-debounce">Debounce (s)</label>
<input type="number" id="cfg-watcher-debounce" class="config-input config-input--num" min="0.5" max="10" step="0.5" value="2">
<span class="config-hint">Délai avant traitement des changements groupés (0.510 secondes)</span>
</div>
</section>
<!-- Diagnostics -->
<section class="config-section">
<h2>Diagnostics</h2>
<p class="config-description">Statistiques de l'index et du moteur de recherche.</p>
<div id="config-diagnostics" class="config-diagnostics">
<div class="config-diag-loading">Chargement...</div>
</div>
<button class="config-btn-secondary" id="cfg-refresh-diag" style="margin-top:8px">Rafraîchir</button>
</section>
</div>
</div>
</div>
</div>
<!-- Help Modal -->
<div class="editor-modal" id="help-modal">
<div class="editor-container help-container">
<div class="editor-header">
<div class="editor-title" id="help-title">Guide d'utilisation ObsiGate</div>
<div class="editor-actions">
<button class="editor-btn" id="help-close" title="Fermer l'aide" aria-label="Fermer l'aide">
<i data-lucide="x" style="width:16px;height:16px"></i>
</button>
</div>
</div>
<div class="editor-body help-body" id="help-body">
<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-astuces" class="help-nav-link">Astuces</a></li>
</ul>
</nav>
<div class="help-content">
<section class="help-section" id="help-intro">
<h1>📘 Bienvenue dans ObsiGate</h1>
<p class="help-lead">ObsiGate est votre porte d'entrée web vers vos vaults Obsidian. Accédez, naviguez et recherchez dans toutes vos notes depuis n'importe quel appareil via une interface moderne et responsive.</p>
<div class="help-badges">
<span class="help-badge">⚡ Navigation rapide</span>
<span class="help-badge">🗂️ Multi-vault</span>
<span class="help-badge">🏷️ Tags intelligents</span>
<span class="help-badge">📝 Lecture et édition</span>
<span class="help-badge">🔍 Recherche TF-IDF</span>
</div>
</section>
<section class="help-section" id="help-interface">
<h2>🧭 Interface utilisateur</h2>
<h3>En-tête</h3>
<p>La barre supérieure contient les éléments essentiels :</p>
<ul>
<li><strong>Bouton menu hamburger</strong> (mobile) : Affiche/masque la sidebar</li>
<li><strong>Bouton toggle sidebar</strong> (desktop) : Masque la sidebar pour plus d'espace</li>
<li><strong>Logo ObsiGate</strong> : Retour à l'accueil</li>
<li><strong>Barre de recherche</strong> : Recherche globale avec autocomplétion</li>
<li><strong>Indicateur de vault</strong> : Affiche le contexte actif (All, vault1, etc.)</li>
<li><strong>Menu Options</strong> : Accès aux paramètres, thème, aide</li>
</ul>
<h3>Sidebar (barre latérale)</h3>
<p>La sidebar est divisée en deux onglets :</p>
<ul>
<li><strong>Vaults</strong> : Arborescence des fichiers et dossiers</li>
<li><strong>Tags</strong> : Nuage de tags cliquables</li>
</ul>
<p>Fonctionnalités de la sidebar :</p>
<ul>
<li><strong>Filtrage</strong> : Barre de recherche pour filtrer fichiers/tags</li>
<li><strong>Sélection rapide</strong> : Dropdown pour changer de vault</li>
<li><strong>Redimensionnement</strong> : Glissez le bord droit pour ajuster la largeur</li>
<li><strong>Masquage</strong> : Cliquez sur l'icône sidebar dans le header</li>
</ul>
<h3>Zone de contenu</h3>
<p>La zone centrale affiche :</p>
<ul>
<li><strong>Breadcrumb</strong> : Chemin du fichier (cliquable pour repositionner la sidebar)</li>
<li><strong>Titre et tags</strong> : Métadonnées du fichier</li>
<li><strong>Boutons d'action</strong> : Copier, Source, Télécharger, Éditer, Ouvrir dans nouvelle fenêtre</li>
<li><strong>Contenu rendu</strong> : Markdown avec wikilinks et images</li>
</ul>
</section>
<section class="help-section" id="help-navigation">
<h2>🗺️ Navigation</h2>
<h3>Arborescence des vaults</h3>
<p>Cliquez sur un vault pour l'ouvrir et voir son contenu. Les dossiers affichent un chevron et un badge avec le nombre d'éléments.</p>
<ul>
<li><strong>Développer/Réduire</strong> : Cliquez sur un dossier</li>
<li><strong>Ouvrir un fichier</strong> : Cliquez sur le nom du fichier</li>
<li><strong>Icônes</strong> : Chaque type de fichier a son icône (markdown, code, etc.)</li>
</ul>
<h3>Filtrage de la sidebar</h3>
<p>Utilisez la barre de filtrage en haut de la sidebar pour rechercher rapidement :</p>
<ul>
<li><strong>Recherche instantanée</strong> : Tapez pour filtrer fichiers et dossiers</li>
<li><strong>Case-sensitive</strong> : Bouton "Aa" pour respecter la casse</li>
<li><strong>Effacer</strong> : Bouton "×" pour réinitialiser le filtre</li>
<li><strong>Résultats groupés</strong> : Affichage par vault avec chemins complets</li>
</ul>
<h3>Breadcrumb et repositionnement</h3>
<p>Le chemin affiché au-dessus du contenu est interactif :</p>
<ul>
<li><strong>Cliquez sur le vault</strong> : Focus sur le vault dans la sidebar</li>
<li><strong>Cliquez sur un segment</strong> : Navigation vers ce dossier</li>
<li><strong>Auto-scroll</strong> : La sidebar se positionne automatiquement</li>
</ul>
<h3>Sélection de vault</h3>
<p>Changez de contexte pour filtrer l'affichage :</p>
<ul>
<li><strong>Menu header</strong> : Dropdown "Vault" dans le menu Options</li>
<li><strong>Sidebar dropdown</strong> : Sélection rapide en haut de l'onglet Vaults</li>
<li><strong>Tous les vaults</strong> : Vue globale de tous vos contenus</li>
<li><strong>Vault spécifique</strong> : Focus sur un seul vault</li>
</ul>
</section>
<section class="help-section" id="help-recherche">
<h2>🔍 Recherche</h2>
<h3>Recherche simple</h3>
<p>Tapez dans la barre de recherche en haut pour lancer une recherche fulltext :</p>
<ul>
<li><strong>Recherche dans tout</strong> : Titre, contenu, tags, chemins</li>
<li><strong>Scoring intelligent</strong> : Résultats classés par pertinence TF-IDF</li>
<li><strong>Snippets surlignés</strong> : Extraits avec termes en surbrillance</li>
<li><strong>Pagination</strong> : Navigation par pages de 50 résultats</li>
</ul>
<h3>Opérateurs avancés</h3>
<p>Utilisez des opérateurs pour affiner votre recherche :</p>
<ul>
<li><code>tag:docker</code> ou <code>#docker</code> : Filtrer par tag</li>
<li><code>vault:IT</code> : Rechercher dans un vault spécifique</li>
<li><code>title:kubernetes</code> : Chercher dans les titres uniquement</li>
<li><code>path:recettes/soupes</code> : Filtrer par chemin</li>
<li><code>"phrase exacte"</code> : Recherche de phrase entre guillemets</li>
</ul>
<p><strong>Exemple</strong> : <code>tag:linux vault:IT serveur web</code> recherche "serveur web" dans le vault IT avec le tag linux.</p>
<h3>Autocomplétion</h3>
<p>L'autocomplétion vous aide à trouver rapidement :</p>
<ul>
<li><strong>Historique</strong> : Les 50 dernières recherches (localStorage)</li>
<li><strong>Fichiers</strong> : Suggestions de titres de fichiers</li>
<li><strong>Tags</strong> : Suggestions de tags avec compteurs</li>
<li><strong>Navigation clavier</strong> : ↑/↓ pour naviguer, Enter pour sélectionner</li>
</ul>
<h3>Chips de filtres actifs</h3>
<p>Les opérateurs utilisés s'affichent sous forme de chips colorés :</p>
<ul>
<li><strong>Visualisation</strong> : Voir d'un coup d'œil les filtres actifs</li>
<li><strong>Suppression</strong> : Cliquez sur "×" pour retirer un filtre</li>
<li><strong>Couleurs</strong> : Chaque type d'opérateur a sa couleur</li>
</ul>
<h3>Facettes et tri</h3>
<p>Les résultats incluent des facettes pour affiner :</p>
<ul>
<li><strong>Facettes tags</strong> : Compteurs par tag dans les résultats</li>
<li><strong>Facettes vaults</strong> : Compteurs par vault</li>
<li><strong>Tri par pertinence</strong> : Score TF-IDF (défaut)</li>
<li><strong>Tri par date</strong> : Dernière modification</li>
</ul>
</section>
<section class="help-section" id="help-tags">
<h2>🏷️ Tags</h2>
<h3>Tag cloud</h3>
<p>L'onglet Tags de la sidebar affiche un nuage de tags :</p>
<ul>
<li><strong>Tous les tags</strong> : Extraits des frontmatters YAML et inline (#tag)</li>
<li><strong>Cliquable</strong> : Cliquez pour filtrer les résultats</li>
<li><strong>Filtrage</strong> : Utilisez la barre de filtrage pour chercher un tag</li>
<li><strong>Contexte vault</strong> : Les tags s'adaptent au vault sélectionné</li>
</ul>
<h3>Tags inline vs frontmatter</h3>
<p>ObsiGate supporte deux types de tags :</p>
<ul>
<li><strong>Frontmatter YAML</strong> : <code>tags: [docker, linux]</code> ou <code>tags: docker, linux</code></li>
<li><strong>Inline</strong> : <code>#docker</code> dans le contenu markdown</li>
<li><strong>Fusion automatique</strong> : Les deux types sont combinés</li>
</ul>
<h3>Filtrage de tags template</h3>
<p>Dans les Configurations, vous pouvez masquer les tags de template :</p>
<ul>
<li><strong>Patterns wildcards</strong> : Ex: <code>#&lt;% ... %&gt;</code> ou <code>#{{ ... }}</code></li>
<li><strong>Regex générée</strong> : Aperçu de la regex appliquée</li>
<li><strong>Ajout/Suppression</strong> : Gérez vos patterns de filtrage</li>
</ul>
</section>
<section class="help-section" id="help-fichiers">
<h2>📄 Fichiers</h2>
<h3>Visualisation</h3>
<p>Les fichiers markdown sont rendus avec :</p>
<ul>
<li><strong>Wikilinks cliquables</strong> : <code>[[lien]]</code> et <code>[[lien|texte]]</code></li>
<li><strong>Images Obsidian</strong> : Support de <code>![[image.png]]</code></li>
<li><strong>Syntax highlighting</strong> : Coloration des blocs de code</li>
<li><strong>Tables, listes, quotes</strong> : Rendu complet du markdown</li>
</ul>
<h3>Actions sur fichiers</h3>
<p>Boutons disponibles au-dessus du contenu :</p>
<ul>
<li><strong>Copier</strong> : Copie le contenu source dans le presse-papiers</li>
<li><strong>Source</strong> : Affiche/masque le markdown brut</li>
<li><strong>Télécharger</strong> : Télécharge le fichier</li>
<li><strong>Éditer</strong> : Ouvre l'éditeur CodeMirror</li>
<li><strong>Ouvrir dans nouvelle fenêtre</strong> : Ouvre le fichier dans un nouvel onglet</li>
</ul>
<h3>Édition avec CodeMirror 6</h3>
<p>L'éditeur intégré offre :</p>
<ul>
<li><strong>Coloration syntaxique</strong> : Support de nombreux langages</li>
<li><strong>Numéros de ligne</strong> : Navigation facile</li>
<li><strong>Autocomplétion</strong> : Suggestions contextuelles</li>
<li><strong>Recherche</strong> : Ctrl+F pour chercher dans le fichier</li>
<li><strong>Sauvegarde</strong> : Bouton ✓ pour enregistrer</li>
<li><strong>Suppression</strong> : Bouton corbeille pour supprimer</li>
</ul>
<h3>Types de fichiers supportés</h3>
<p>ObsiGate indexe et affiche :</p>
<ul>
<li><strong>Markdown</strong> : .md (rendu complet)</li>
<li><strong>Code</strong> : .py, .js, .ts, .jsx, .tsx, .java, .c, .cpp, .rs, .go, etc.</li>
<li><strong>Config</strong> : .json, .yaml, .yml, .toml, .xml, .ini, .env</li>
<li><strong>Scripts</strong> : .sh, .bash, .ps1, .bat</li>
<li><strong>Web</strong> : .html, .css, .scss</li>
<li><strong>Autres</strong> : .txt, .log, .sql, .csv</li>
</ul>
</section>
<section class="help-section" id="help-personnalisation">
<h2>🎨 Personnalisation</h2>
<h3>Thème clair/sombre</h3>
<p>Basculez entre les thèmes :</p>
<ul>
<li><strong>Menu Options</strong> : Cliquez sur "Thème" dans le menu</li>
<li><strong>Raccourci</strong> : <code>Ctrl+T</code></li>
<li><strong>Persistance</strong> : Votre choix est sauvegardé en localStorage</li>
<li><strong>Highlight.js</strong> : Les blocs de code s'adaptent au thème</li>
</ul>
<h3>Redimensionnement de la sidebar</h3>
<p>Sur desktop, ajustez la largeur de la sidebar :</p>
<ul>
<li><strong>Handle de redimensionnement</strong> : Bordure droite de la sidebar</li>
<li><strong>Glisser-déposer</strong> : Cliquez et glissez pour ajuster</li>
<li><strong>Limites</strong> : Min 200px, Max 500px</li>
<li><strong>Persistance</strong> : La largeur est sauvegardée</li>
</ul>
<h3>Configuration avancée</h3>
<p>Le modal Configurations (menu Options) permet de :</p>
<ul>
<li><strong>Paramètres de recherche</strong> : Délai debounce, résultats par page, timeout</li>
<li><strong>Paramètres backend</strong> : Workers, boosts TF-IDF, expansions préfixe</li>
<li><strong>Filtrage de tags</strong> : Patterns pour masquer les tags template</li>
<li><strong>Diagnostics</strong> : Stats index, mémoire, moteur de recherche</li>
<li><strong>Réindexation</strong> : Forcer un rescan des vaults</li>
</ul>
</section>
<section class="help-section" id="help-raccourcis">
<h2>⌨️ Raccourcis clavier</h2>
<h3>Navigation</h3>
<ul>
<li><code>Ctrl+K</code> ou <code>Cmd+K</code> : Focaliser la barre de recherche</li>
<li><code>/</code> : Focaliser la recherche (hors champ texte)</li>
<li><code>Escape</code> : Fermer les suggestions / quitter la recherche</li>
</ul>
<h3>Recherche et autocomplétion</h3>
<ul>
<li><code></code> / <code></code> : Naviguer dans les suggestions</li>
<li><code>Enter</code> : Sélectionner la suggestion active ou lancer la recherche</li>
<li><code>Escape</code> : Fermer le dropdown de suggestions</li>
</ul>
<h3>Interface</h3>
<ul>
<li><code>Ctrl+T</code> : Basculer le thème clair/sombre</li>
</ul>
<h3>Éditeur CodeMirror</h3>
<ul>
<li><code>Ctrl+F</code> : Rechercher dans le fichier</li>
<li><code>Ctrl+Z</code> : Annuler</li>
<li><code>Ctrl+Y</code> : Refaire</li>
<li><code>Ctrl+S</code> : Sauvegarder (si configuré)</li>
</ul>
</section>
<section class="help-section" id="help-astuces">
<h2>💡 Astuces et bonnes pratiques</h2>
<h3>Workflow recommandé</h3>
<ol>
<li><strong>Sélectionnez un contexte</strong> : Choisissez un vault pour réduire le bruit</li>
<li><strong>Explorez l'arborescence</strong> : Naviguez dans les dossiers</li>
<li><strong>Utilisez les tags</strong> : Filtrez par tags pour affiner</li>
<li><strong>Recherchez intelligemment</strong> : Combinez opérateurs et texte libre</li>
<li><strong>Profitez de l'historique</strong> : Réutilisez vos recherches fréquentes</li>
</ol>
<h3>Optimisations</h3>
<ul>
<li><strong>Masquez la sidebar</strong> : Plus d'espace pour le contenu</li>
<li><strong>Utilisez le filtrage sidebar</strong> : Plus rapide que la recherche globale pour trouver un fichier</li>
<li><strong>Favorisez les opérateurs</strong> : <code>tag:</code> et <code>vault:</code> accélèrent la recherche</li>
<li><strong>Breadcrumb cliquable</strong> : Repositionnez rapidement la sidebar</li>
</ul>
<h3>Trucs et astuces</h3>
<ul>
<li><strong>Navigation visuelle</strong> : Le breadcrumb repositionne automatiquement la sidebar</li>
<li><strong>Gestion de l'espace</strong> : Réduisez les sections Vaults/Tags selon vos besoins</li>
<li><strong>Confort de lecture</strong> : Ajustez la largeur de la sidebar</li>
<li><strong>Mobile-friendly</strong> : Utilisez le bouton hamburger sur mobile</li>
<li><strong>Wikilinks</strong> : Naviguez entre notes comme dans Obsidian</li>
<li><strong>Images</strong> : Support complet des syntaxes Obsidian</li>
</ul>
<h3>Cas d'usage avancés</h3>
<ul>
<li><strong>Recherche multi-critères</strong> : <code>tag:docker tag:linux vault:IT nginx</code></li>
<li><strong>Exploration par tags</strong> : Cliquez sur un tag dans une note pour voir toutes les notes similaires</li>
<li><strong>Édition rapide</strong> : Ouvrez l'éditeur, modifiez, sauvegardez</li>
<li><strong>Export</strong> : Téléchargez des fichiers pour backup ou partage</li>
<li><strong>Multi-fenêtres</strong> : Ouvrez plusieurs notes dans des onglets séparés</li>
</ul>
</section>
<div class="help-footer">
<p><strong>ObsiGate v1.2.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>
</div>
</div>
</div>
<script src="/static/app.js"></script>
</body>
</html>