- Filtres de chemin: changed to data-i18n-attr - help close/hide/clear buttons: changed to data-i18n-attr - aria-label spans: changed to data-i18n-attr - This fixes the visible HTML tag leakage in the UI
4845 lines
257 KiB
HTML
4845 lines
257 KiB
HTML
<!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 data-i18n="header.logo">ObsiGate</title>
|
||
|
||
<!-- PWA Meta Tags -->
|
||
<meta
|
||
name="description"
|
||
content="Porte d'entrée web pour vos vaults Obsidian - Accédez, naviguez et recherchez dans toutes vos notes"
|
||
/>
|
||
<meta name="theme-color" content="#2563eb" />
|
||
<meta name="mobile-web-app-capable" content="yes" />
|
||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||
<meta
|
||
name="apple-mobile-web-app-status-bar-style"
|
||
content="black-translucent"
|
||
/>
|
||
<meta name="apple-mobile-web-app-title" content="ObsiGate" />
|
||
|
||
<!-- PWA Manifest -->
|
||
<link rel="manifest" href="/static/manifest.json" />
|
||
|
||
<!-- Apple Touch Icons -->
|
||
<link
|
||
rel="apple-touch-icon"
|
||
sizes="152x152"
|
||
href="/static/icons/icon-152x152.svg"
|
||
/>
|
||
<link
|
||
rel="apple-touch-icon"
|
||
sizes="192x192"
|
||
href="/static/icons/icon-192x192.svg"
|
||
/>
|
||
|
||
<!-- Favicon -->
|
||
<link
|
||
rel="icon"
|
||
type="image/svg+xml"
|
||
href="/static/icons/icon-72x72.svg"
|
||
/>
|
||
<link
|
||
rel="icon"
|
||
type="image/svg+xml"
|
||
sizes="192x192"
|
||
href="/static/icons/icon-192x192.svg"
|
||
/>
|
||
|
||
<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/[email protected]/dist/umd/lucide.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js"></script>
|
||
<script type="importmap">
|
||
{
|
||
"imports": {
|
||
"@codemirror/state": "https://esm.sh/@codemirror/[email protected]"
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<!-- CodeMirror 6 -->
|
||
<script type="module">
|
||
import {
|
||
EditorView,
|
||
keymap,
|
||
lineNumbers,
|
||
highlightActiveLineGutter,
|
||
highlightSpecialChars,
|
||
drawSelection,
|
||
dropCursor,
|
||
rectangularSelection,
|
||
crosshairCursor,
|
||
highlightActiveLine,
|
||
} from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { EditorState } from "@codemirror/state";
|
||
import {
|
||
defaultHighlightStyle,
|
||
syntaxHighlighting,
|
||
indentOnInput,
|
||
bracketMatching,
|
||
foldGutter,
|
||
foldKeymap,
|
||
} from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import {
|
||
defaultKeymap,
|
||
history,
|
||
historyKeymap,
|
||
} from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import {
|
||
searchKeymap,
|
||
highlightSelectionMatches,
|
||
} from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import {
|
||
autocompletion,
|
||
completionKeymap,
|
||
closeBrackets,
|
||
closeBracketsKeymap,
|
||
} from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { markdown } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { python } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { javascript } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { html } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { css } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { json } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { xml } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { sql } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { php } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { cpp } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { java } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { rust } from "https://esm.sh/@codemirror/[email protected]?external=@codemirror/state";
|
||
import { oneDark } from "https://esm.sh/@codemirror/[email protected]?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" data-i18n="header.logo">ObsiGate</span>
|
||
</div>
|
||
<p class="login-subtitle" data-i18n="auth.login_title">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" data-i18n="auth.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" data-i18n="auth.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 data-i18n="auth.remember_me">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" data-i18n="auth.login_button">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"
|
||
data-i18n-placeholder="header.search_placeholder"
|
||
placeholder="Rechercher ..."
|
||
autocomplete="off"
|
||
/>
|
||
<div class="search-actions">
|
||
<button
|
||
class="search-btn icon-only"
|
||
id="search-filter-btn"
|
||
type="button"
|
||
title="Filtres de chemin (Alt-F)" data-i18n-attr="title:sidebar.filter_path"
|
||
>
|
||
<i
|
||
data-lucide="filter"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="search-btn icon-only"
|
||
id="search-clear-btn"
|
||
type="button"
|
||
title="Effacer" data-i18n-attr="title:help.clear_search"
|
||
aria-label="Effacer la recherche"
|
||
>
|
||
<i
|
||
data-lucide="x"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<!-- Path filter row -->
|
||
<div
|
||
class="search-filter-row"
|
||
id="search-filter-row"
|
||
style="display: none"
|
||
>
|
||
<input
|
||
type="text"
|
||
class="search-filter-input"
|
||
id="search-include-input"
|
||
data-i18n-placeholder="search.include_placeholder" placeholder="Inclure: **/*.md, notes/**"
|
||
/>
|
||
<input
|
||
type="text"
|
||
class="search-filter-input"
|
||
id="search-exclude-input"
|
||
data-i18n-placeholder="search.exclude_placeholder" placeholder="Exclure: vendor/*, *.lock"
|
||
/>
|
||
</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 data-i18n="search.dropdown_history">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 data-i18n="palette.mode_files">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 data-i18n="sidebar.tab_tags">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">
|
||
<!-- Offline indicator (hidden by default) -->
|
||
<div
|
||
class="header-icon offline-indicator"
|
||
id="offline-badge"
|
||
style="display:none"
|
||
title="Mode hors-ligne"
|
||
></div>
|
||
<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 hidden"
|
||
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"
|
||
><span data-i18n="sidebar.all_vaults">Tous les vaults</span></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" data-i18n="help.all_vaults">
|
||
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" data-i18n="header.menu_theme"
|
||
>Thème</span
|
||
>
|
||
<span
|
||
class="menu-list-subtitle"
|
||
id="theme-label"
|
||
>Clair</span
|
||
>
|
||
</span>
|
||
</button>
|
||
<button
|
||
class="menu-list-row menu-list-button hidden"
|
||
id="admin-menu-row"
|
||
type="button"
|
||
role="menuitem"
|
||
>
|
||
<span
|
||
class="menu-list-icon"
|
||
aria-hidden="true"
|
||
>
|
||
<i
|
||
data-lucide="shield"
|
||
style="width: 17px; height: 17px"
|
||
></i>
|
||
</span>
|
||
<span class="menu-list-content">
|
||
<span class="menu-list-title" data-i18n="header.menu_admin"
|
||
>Administration</span
|
||
>
|
||
<span class="menu-list-subtitle" data-i18n="header.menu_admin_desc"
|
||
>Gérer les utilisateurs</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" data-i18n="header.menu_config"
|
||
>Configurations</span
|
||
>
|
||
<span class="menu-list-subtitle" data-i18n="header.menu_config_desc"
|
||
>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" data-i18n="header.menu_help"
|
||
>Guide d'utilisation</span
|
||
>
|
||
<span class="menu-list-subtitle" data-i18n="header.menu_help_desc"
|
||
>Ouvrir l'aide</span
|
||
>
|
||
</span>
|
||
</button>
|
||
<button
|
||
class="menu-list-row menu-list-button"
|
||
id="about-open-btn"
|
||
type="button"
|
||
role="menuitem"
|
||
>
|
||
<span
|
||
class="menu-list-icon"
|
||
aria-hidden="true"
|
||
>
|
||
<i
|
||
data-lucide="sparkles"
|
||
style="width: 17px; height: 17px"
|
||
></i>
|
||
</span>
|
||
<span class="menu-list-content">
|
||
<span class="menu-list-title" data-i18n="header.menu_about"
|
||
>A propos</span
|
||
>
|
||
<span class="menu-list-subtitle" data-i18n="header.menu_about_desc"
|
||
>Version, credits & info</span
|
||
>
|
||
</span>
|
||
</button>
|
||
<button
|
||
class="menu-list-row menu-list-button"
|
||
id="profile-open-btn"
|
||
type="button"
|
||
role="menuitem"
|
||
>
|
||
<span
|
||
class="menu-list-icon"
|
||
aria-hidden="true"
|
||
>
|
||
<i
|
||
data-lucide="user"
|
||
style="width: 17px; height: 17px"
|
||
></i>
|
||
</span>
|
||
<span class="menu-list-content">
|
||
<span class="menu-list-title" data-i18n="header.menu_profile"
|
||
>Profil</span
|
||
>
|
||
<span class="menu-list-subtitle" data-i18n="header.menu_profile_desc"
|
||
>Langue & preferences</span
|
||
>
|
||
</span>
|
||
</button>
|
||
<button
|
||
class="menu-list-row menu-list-button"
|
||
id="logout-btn"
|
||
type="button"
|
||
role="menuitem"
|
||
>
|
||
<span
|
||
class="menu-list-icon"
|
||
aria-hidden="true"
|
||
>
|
||
<i
|
||
data-lucide="log-out"
|
||
style="width: 17px; height: 17px; color: var(--danger)"
|
||
></i>
|
||
</span>
|
||
<span class="menu-list-content">
|
||
<span class="menu-list-title" data-i18n="header.menu_logout"
|
||
style="color:var(--danger)"
|
||
>Deconnexion</span
|
||
>
|
||
<span class="menu-list-subtitle" data-i18n="header.menu_logout_desc"
|
||
>Quitter la session</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"
|
||
data-i18n-placeholder="sidebar.filter_placeholder" 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"
|
||
title="Vaults"
|
||
>
|
||
<i
|
||
data-lucide="folder-tree"
|
||
style="width: 18px; height: 18px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="sidebar-tab"
|
||
id="sidebar-tab-tags"
|
||
role="tab"
|
||
aria-selected="false"
|
||
aria-controls="sidebar-panel-tags"
|
||
data-tab="tags"
|
||
title="Tags"
|
||
>
|
||
<i
|
||
data-lucide="tag"
|
||
style="width: 18px; height: 18px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="sidebar-tab"
|
||
id="sidebar-tab-recent"
|
||
role="tab"
|
||
aria-selected="false"
|
||
aria-controls="sidebar-panel-recent"
|
||
data-tab="recent"
|
||
title="Récent"
|
||
>
|
||
<i
|
||
data-lucide="clock"
|
||
style="width: 18px; height: 18px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="sidebar-tab"
|
||
id="sidebar-tab-saved"
|
||
role="tab"
|
||
aria-selected="false"
|
||
aria-controls="sidebar-panel-saved"
|
||
data-tab="saved"
|
||
title="Sauvegardes"
|
||
>
|
||
<i
|
||
data-lucide="bookmark"
|
||
style="width: 18px; height: 18px"
|
||
></i>
|
||
</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" data-i18n="help.all_vaults">
|
||
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>
|
||
|
||
<!-- Recent panel -->
|
||
<div
|
||
class="sidebar-tab-panel"
|
||
id="sidebar-panel-recent"
|
||
role="tabpanel"
|
||
aria-labelledby="sidebar-tab-recent"
|
||
>
|
||
<div class="recent-filter-bar">
|
||
<select id="recent-vault-filter">
|
||
<option value="" data-i18n="help.all_vaults">Tous les vaults</option>
|
||
</select>
|
||
</div>
|
||
<div id="recent-list" class="recent-list"></div>
|
||
<div id="recent-empty" class="recent-empty hidden">
|
||
<i
|
||
data-lucide="inbox"
|
||
style="width: 32px; height: 32px"
|
||
></i>
|
||
<span data-i18n="dashboard.no_recent">Aucun fichier récent</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Saved Searches panel -->
|
||
<div
|
||
class="sidebar-tab-panel"
|
||
id="sidebar-panel-saved"
|
||
role="tabpanel"
|
||
aria-labelledby="sidebar-tab-saved"
|
||
>
|
||
<div class="saved-filter-bar" id="saved-filter-bar">
|
||
<button class="saved-filter-pill active" data-filter="all" data-i18n="common.all">Tous</button>
|
||
<button class="saved-filter-pill" data-filter="search" data-i18n="sidebar.tab_saved">Recherches</button>
|
||
<button class="saved-filter-pill" data-filter="directory">Repertoires</button>
|
||
</div>
|
||
<div id="saved-searches-list" class="recent-list"></div>
|
||
<div id="saved-searches-empty" class="recent-empty">
|
||
<i
|
||
data-lucide="bookmark"
|
||
style="width: 32px; height: 32px"
|
||
></i>
|
||
<span>Aucune recherche sauvegardee</span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
<!-- Sidebar resize handle -->
|
||
<div
|
||
class="sidebar-resize-handle"
|
||
id="sidebar-resize-handle"
|
||
></div>
|
||
|
||
<!-- Content Wrapper (tab bar + content area) -->
|
||
<div class="vault-context-bar" id="vault-context-bar">
|
||
<span class="vault-context-pill" id="vault-context-pill"
|
||
>📂 Toutes les vaults</span
|
||
>
|
||
</div>
|
||
<div class="content-wrapper">
|
||
<!-- Tab bar -->
|
||
<div class="tab-bar" id="tab-bar" hidden>
|
||
<div class="tab-list" id="tab-list"></div>
|
||
</div>
|
||
|
||
<!-- Content -->
|
||
<main
|
||
class="content-area"
|
||
id="content-area"
|
||
aria-label="Contenu principal"
|
||
>
|
||
<div
|
||
id="dashboard-home"
|
||
class="dashboard-home"
|
||
role="region"
|
||
aria-label="Tableau de bord"
|
||
>
|
||
<!-- Dashboard Tabs -->
|
||
<div class="dashboard-tabs">
|
||
<button
|
||
class="dashboard-tab active"
|
||
data-tab="stats"
|
||
>
|
||
<i
|
||
data-lucide="bar-chart-3"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
<span data-i18n="dashboard.tab_stats">Statistiques</span>
|
||
</button>
|
||
<button
|
||
class="dashboard-tab"
|
||
data-tab="bookmarks"
|
||
>
|
||
<i
|
||
data-lucide="bookmark"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
Bookmarks
|
||
</button>
|
||
<button class="dashboard-tab" data-tab="recent">
|
||
<i
|
||
data-lucide="clock"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
<span data-i18n="dashboard.tab_recent">Récents</span>
|
||
</button>
|
||
<button class="dashboard-tab" data-tab="shared">
|
||
<i
|
||
data-lucide="share-2"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
<span data-i18n="dashboard.tab_shared">Partagés</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- Stats Panel -->
|
||
<div
|
||
id="dashboard-panel-stats"
|
||
class="dashboard-panel active"
|
||
>
|
||
<div
|
||
id="dashboard-stats-grid"
|
||
class="dashboard-stats-grid"
|
||
>
|
||
<div class="dashboard-stats-loading" data-i18n="common.loading">
|
||
Chargement...
|
||
</div>
|
||
</div>
|
||
<div
|
||
id="dashboard-conflicts-container"
|
||
style="margin-top: 16px"
|
||
></div>
|
||
<!-- Quick Help -->
|
||
<div class="quick-help" id="quick-help">
|
||
<div class="qh-header">
|
||
<i
|
||
data-lucide="keyboard"
|
||
style="width: 16px; height: 16px"
|
||
></i>
|
||
<span data-i18n="help.shortcuts_title">Raccourcis & Astuces</span>
|
||
<button
|
||
class="qh-toggle"
|
||
id="qh-toggle"
|
||
title="Masquer"
|
||
aria-label="Masquer l'aide" data-i18n-attr="aria-label:help.hide_help"
|
||
>
|
||
−
|
||
</button>
|
||
</div>
|
||
<div class="qh-body" id="qh-body">
|
||
<div class="qh-row">
|
||
<span class="qh-kbd"
|
||
>Ctrl+Shift+Space</span
|
||
>
|
||
<span class="qh-desc" data-i18n="help.shortcut_command_palette"
|
||
>Palette de commandes</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd"
|
||
>Ctrl+Alt+Space</span
|
||
>
|
||
<span class="qh-desc" data-i18n="help.shortcut_file_palette"
|
||
>Palette de fichiers (nav.
|
||
rapide)</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">Ctrl+K</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_focus_search"
|
||
>Focus barre de recherche</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">/</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_quick_search"
|
||
>Recherche rapide (hors champ
|
||
texte)</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">Ctrl+S</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_save_file"
|
||
>Sauvegarder le fichier
|
||
ouvert</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">Ctrl+F</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_search_doc"
|
||
>Rechercher dans le
|
||
document</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">Esc</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_close_editor"
|
||
>Fermer l'editeur / modale</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">Ctrl+J</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_ai_completion"
|
||
>Completion IA inline (dans
|
||
l'editeur)</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">Alt+I</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_quick_insert"
|
||
>Insertion rapide (editeur
|
||
Forge)</span
|
||
>
|
||
</div>
|
||
<div class="qh-row">
|
||
<span class="qh-kbd">F1</span>
|
||
<span class="qh-desc" data-i18n="help.shortcut_forge_help"
|
||
>Aide de l'editeur Forge</span
|
||
>
|
||
</div>
|
||
<div class="qh-divider"></div>
|
||
<div class="qh-tip">
|
||
<i
|
||
data-lucide="lightbulb"
|
||
style="
|
||
width: 14px;
|
||
height: 14px;
|
||
"
|
||
></i>
|
||
<span
|
||
>Survolez un document avec
|
||
<strong>Ctrl</strong> pour un
|
||
apercu rapide. Cliquez sur
|
||
<strong>Forge</strong> dans la
|
||
barre d'outils pour l'editeur
|
||
avance.</span
|
||
>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Bookmarks Panel -->
|
||
<div
|
||
id="dashboard-panel-bookmarks"
|
||
class="dashboard-panel"
|
||
>
|
||
<div
|
||
id="dashboard-bookmarks-grid"
|
||
class="dashboard-recent-grid"
|
||
></div>
|
||
<div
|
||
id="dashboard-bookmarks-empty"
|
||
class="dashboard-recent-empty"
|
||
>
|
||
<i data-lucide="pin"></i>
|
||
<span>Aucun bookmark</span>
|
||
<p data-i18n="auto.c089d968">
|
||
Épinglez des fichiers pour les retrouver
|
||
ici.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Recent Panel -->
|
||
<div
|
||
id="dashboard-panel-recent"
|
||
class="dashboard-panel"
|
||
>
|
||
<div class="dashboard-header">
|
||
<div class="dashboard-title-row">
|
||
<span
|
||
id="dashboard-count"
|
||
class="dashboard-badge"
|
||
></span>
|
||
</div>
|
||
</div>
|
||
<div
|
||
id="dashboard-recent-grid"
|
||
class="dashboard-recent-grid"
|
||
></div>
|
||
<div
|
||
id="dashboard-loading"
|
||
class="dashboard-loading"
|
||
>
|
||
<div class="skeleton-card"></div>
|
||
<div class="skeleton-card"></div>
|
||
<div class="skeleton-card"></div>
|
||
<div class="skeleton-card"></div>
|
||
<div class="skeleton-card"></div>
|
||
<div class="skeleton-card"></div>
|
||
</div>
|
||
<div
|
||
id="dashboard-recent-empty"
|
||
class="dashboard-recent-empty hidden"
|
||
>
|
||
<i data-lucide="inbox"></i>
|
||
<span data-i18n="dashboard.no_recent">Aucun fichier récent</span>
|
||
<p data-i18n="auto.753d30a8">
|
||
Ouvrez un fichier pour le voir
|
||
apparaître ici
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Shared Panel -->
|
||
<div
|
||
id="dashboard-panel-shared"
|
||
class="dashboard-panel"
|
||
>
|
||
<div
|
||
id="dashboard-shared-grid"
|
||
class="dashboard-recent-grid"
|
||
></div>
|
||
<div
|
||
id="dashboard-shared-empty"
|
||
class="dashboard-recent-empty"
|
||
>
|
||
<i data-lucide="share-2"></i>
|
||
<span data-i18n="dashboard.no_shares">Aucun document partagé</span>
|
||
<p data-i18n="auto.e61598c1">
|
||
Partagez un document pour le voir
|
||
apparaître ici
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
<!-- /content-wrapper -->
|
||
|
||
<!-- Right sidebar resize handle -->
|
||
<div
|
||
class="right-sidebar-resize-handle"
|
||
id="right-sidebar-resize-handle"
|
||
></div>
|
||
|
||
<!-- Right Sidebar (Outline/TOC) -->
|
||
<aside
|
||
class="right-sidebar"
|
||
id="right-sidebar"
|
||
role="complementary"
|
||
aria-label="Table des matières"
|
||
>
|
||
<div class="right-sidebar-header">
|
||
<h2 class="right-sidebar-title" data-i18n="viewer.on_this_page">SUR CETTE PAGE</h2>
|
||
<button
|
||
class="right-sidebar-toggle-btn"
|
||
id="right-sidebar-toggle-btn"
|
||
type="button"
|
||
title="Masquer le panneau"
|
||
aria-label="Masquer le panneau"
|
||
>
|
||
<i
|
||
data-lucide="chevron-right"
|
||
style="width: 16px; height: 16px"
|
||
></i>
|
||
</button>
|
||
</div>
|
||
<div class="outline-panel" id="outline-panel">
|
||
<nav
|
||
class="outline-list"
|
||
id="outline-list"
|
||
role="navigation"
|
||
aria-label="Navigation dans le document"
|
||
>
|
||
<!-- Outline items will be injected here -->
|
||
</nav>
|
||
<div class="outline-empty" id="outline-empty" hidden>
|
||
<i
|
||
data-lucide="list"
|
||
style="width: 24px; height: 24px; opacity: 0.3"
|
||
></i>
|
||
<span data-i18n="viewer.no_headings">Aucun titre dans ce document</span>
|
||
</div>
|
||
</div>
|
||
<div class="reading-progress" id="reading-progress">
|
||
<div class="reading-progress-bar">
|
||
<div
|
||
class="reading-progress-fill"
|
||
id="reading-progress-fill"
|
||
></div>
|
||
</div>
|
||
<div
|
||
class="reading-progress-text"
|
||
id="reading-progress-text"
|
||
>
|
||
0%
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Editor Modal -->
|
||
<div class="editor-modal" id="editor-modal">
|
||
<div class="editor-container">
|
||
<div class="editor-header">
|
||
<span class="editor-brand" data-i18n="header.logo">ObsiGate</span>
|
||
<input
|
||
class="editor-title-input"
|
||
id="editor-title-input"
|
||
data-i18n-placeholder="forge.title_placeholder" placeholder="Titre..."
|
||
spellcheck="false"
|
||
title="Titre (sync avec # Heading)"
|
||
/>
|
||
<span class="editor-sep">/</span>
|
||
<input
|
||
class="editor-filename-input"
|
||
id="editor-filename-input"
|
||
placeholder="nom.md"
|
||
spellcheck="false"
|
||
title="Renommer le fichier"
|
||
/>
|
||
<div class="editor-spacer"></div>
|
||
<span class="editor-save-dot ok" id="editor-save-dot"
|
||
><span class="dot"></span
|
||
><span id="editor-save-label">Saved</span></span
|
||
>
|
||
<button
|
||
class="editor-btn danger"
|
||
id="editor-delete"
|
||
title="Supprimer"
|
||
aria-label="Supprimer"
|
||
>
|
||
🗑
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="editor-cancel"
|
||
title="Annuler"
|
||
aria-label="Annuler"
|
||
>
|
||
✕
|
||
</button>
|
||
<button
|
||
class="editor-btn primary"
|
||
id="editor-save"
|
||
title="Sauvegarder"
|
||
aria-label="Sauvegarder"
|
||
>
|
||
✓
|
||
</button>
|
||
</div>
|
||
<div class="editor-body editor-body-cm" id="editor-body">
|
||
<div id="ai-toolbar-container"></div>
|
||
</div>
|
||
<div class="editor-footer">
|
||
<span class="editor-stat-file" id="editor-stat-file"></span>
|
||
<span class="editor-stat-words" id="editor-stat-words"
|
||
>0 words</span
|
||
>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Configurations Modal -->
|
||
<div class="editor-modal" id="config-modal">
|
||
<div class="editor-container">
|
||
<div class="editor-header">
|
||
<div class="editor-title" data-i18n="header.menu_config">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 help-body" id="config-body">
|
||
<nav class="help-nav" id="config-nav">
|
||
<div class="help-nav-header">
|
||
<div class="help-nav-title" data-i18n="config.title">Configuration</div>
|
||
</div>
|
||
<div class="help-nav-search-wrap">
|
||
<input
|
||
type="text"
|
||
class="help-nav-search"
|
||
id="config-nav-search"
|
||
data-i18n-placeholder="settings.search_placeholder" placeholder="Rechercher..."
|
||
autocomplete="off"
|
||
spellcheck="false"
|
||
/>
|
||
<button
|
||
class="help-search-clear"
|
||
id="config-search-clear"
|
||
title="Effacer"
|
||
onclick="
|
||
var s =
|
||
document.getElementById(
|
||
'config-nav-search',
|
||
);
|
||
if (s) {
|
||
s.value = '';
|
||
s.dispatchEvent(new Event('input'));
|
||
s.focus();
|
||
}
|
||
"
|
||
>
|
||
X
|
||
</button>
|
||
</div>
|
||
<ul class="help-nav-list">
|
||
<li>
|
||
<a href="#cfg-search" class="help-nav-link"
|
||
data-i18n="help.nav_search">🔍 Recherche</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#cfg-backend" class="help-nav-link"
|
||
>⚙️ Backend</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#cfg-sync" class="help-nav-link"
|
||
data-i18n="settings.sync">🔄 Synchronisation</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#cfg-diags" class="help-nav-link"
|
||
data-i18n="settings.diagnostics">🩺 Diagnostics</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#cfg-ai" class="help-nav-link"
|
||
data-i18n="settings.ai">🤖 IA</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#cfg-profile" class="help-nav-link"
|
||
data-i18n="settings.profile">👤 Profil</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#cfg-about" class="help-nav-link"
|
||
data-i18n="settings.about">📦 A propos</a
|
||
>
|
||
<a href="#cfg-themes" class="help-nav-link"
|
||
data-i18n="settings.themes">🎨 Themes</a
|
||
>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
<div class="help-content" id="config-scroll">
|
||
<div class="config-content">
|
||
<!-- Performance Settings - Frontend -->
|
||
<section
|
||
class="config-section help-section"
|
||
id="cfg-search"
|
||
>
|
||
<h2 data-i18n="config.section_search">Paramètres de recherche</h2>
|
||
<p class="config-description" data-i18n="auto.7e13c97a">
|
||
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
|
||
(100-2000)</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
|
||
(10-200)</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 (1-5)</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
|
||
(5000-120000)</span
|
||
>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Historique récent -->
|
||
<section class="config-section help-section">
|
||
<h2>
|
||
📋 Historique récent
|
||
<span class="config-badge-restart"
|
||
>Redémarrage non requis</span
|
||
>
|
||
</h2>
|
||
<div class="config-row">
|
||
<label
|
||
class="config-label"
|
||
for="cfg-recent-limit"
|
||
>Nombre de fichiers dans
|
||
l'historique</label
|
||
>
|
||
<input
|
||
type="number"
|
||
id="cfg-recent-limit"
|
||
class="config-input config-input--num"
|
||
min="5"
|
||
max="100"
|
||
step="5"
|
||
value="20"
|
||
/>
|
||
<span class="config-hint"
|
||
>Entre 5 et 100 fichiers (sauvegarde sur
|
||
le serveur)</span
|
||
>
|
||
</div>
|
||
<div class="config-row">
|
||
<label
|
||
class="config-label"
|
||
for="cfg-max-backups"
|
||
>Max backups par fichier</label
|
||
>
|
||
<input
|
||
type="number"
|
||
id="cfg-max-backups"
|
||
class="config-input config-input--num"
|
||
min="1"
|
||
max="50"
|
||
step="1"
|
||
value="10"
|
||
/>
|
||
<span class="config-hint"
|
||
>Nombre maximum de versions backup
|
||
conservees par fichier (1-50)</span
|
||
>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Performance Settings - Backend -->
|
||
<section class="config-section help-section">
|
||
<h2>
|
||
Paramètres backend
|
||
<span class="config-badge-restart"
|
||
>Redémarrage requis</span
|
||
>
|
||
</h2>
|
||
<p class="config-description" data-i18n="auto.b114ed1c">
|
||
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
|
||
(1-8)</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 (10K-1M).
|
||
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 (10-200)</span
|
||
>
|
||
</div>
|
||
|
||
<div class="config-actions-row">
|
||
<button class="config-btn-save"
|
||
id="cfg-save-backend" data-i18n="help.shortcut_save">
|
||
><span data-i18n="sidebar.tab_backups">Sauvegardes</span>
|
||
</button>
|
||
<button class="config-btn-secondary"
|
||
id="cfg-reindex" data-i18n="settings.reindex">
|
||
Forcer réindexation
|
||
</button>
|
||
<button class="config-btn-secondary"
|
||
id="cfg-reset-defaults" data-i18n="config.reset">
|
||
Réinitialiser
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Tag Filtering (existing) -->
|
||
<section class="config-section help-section">
|
||
<h2 data-i18n="config.tag_filtering_label">Filtrage de tags</h2>
|
||
<p class="config-description" data-i18n="auto.e0b8a606">
|
||
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: #<% ... %> ou #{{ ... }}"
|
||
class="config-input"
|
||
/>
|
||
<button id="config-add-btn"
|
||
class="config-btn-add" data-i18n="config.add_webhook">
|
||
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 help-section"
|
||
id="cfg-sync"
|
||
>
|
||
<h2 data-i18n="config.section_watcher">Synchronisation automatique</h2>
|
||
<p class="config-description" data-i18n="auto.d33601dc">
|
||
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 (1-30 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.5-10 secondes)</span
|
||
>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Hidden Files/Folders Configuration -->
|
||
<section class="config-section help-section">
|
||
<h2 data-i18n="auto.f8ba6127">🗂️ Fichiers cachés</h2>
|
||
<p class="config-description">
|
||
Contrôlez l'affichage des fichiers/dossiers
|
||
cachés (commençant par <code>.</code>) par
|
||
vault.
|
||
</p>
|
||
<p
|
||
class="config-hint"
|
||
style="
|
||
margin-bottom: 12px;
|
||
padding: 8px;
|
||
background: var(--background-secondary);
|
||
border-radius: 4px;
|
||
"
|
||
>
|
||
i️ <strong data-i18n="config.note">Note :</strong> Tous les fichiers
|
||
sont toujours indexés et cherchables. Ce
|
||
paramètre contrôle uniquement leur
|
||
visibilité dans l'interface.
|
||
</p>
|
||
|
||
<div id="hidden-files-vault-list">
|
||
<!-- Vault-specific settings will be injected here -->
|
||
</div>
|
||
|
||
<div
|
||
class="config-actions-row"
|
||
style="margin-top: 16px"
|
||
>
|
||
<button
|
||
class="config-btn-save"
|
||
id="cfg-save-hidden-files"
|
||
>
|
||
><span data-i18n="sidebar.tab_backups">Sauvegardes</span>
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Diagnostics -->
|
||
<section
|
||
class="config-section help-section"
|
||
id="cfg-diags"
|
||
>
|
||
<h2 data-i18n="config.diagnostics">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" data-i18n="common.loading">
|
||
Chargement...
|
||
</div>
|
||
</div>
|
||
<button class="config-btn-secondary"
|
||
id="cfg-refresh-diag"
|
||
style="margin-top: 8px" data-i18n="header.refresh">
|
||
Rafraîchir
|
||
</button>
|
||
</section>
|
||
|
||
<!-- Cles API AI -->
|
||
<section
|
||
class="config-section help-section"
|
||
id="cfg-ai"
|
||
>
|
||
<h2>🤖 Cles API Intelligence Artificielle</h2>
|
||
<p class="config-description">
|
||
Configurez vos cles API. Cliquez sur
|
||
<strong data-i18n="config.test">Tester</strong> pour charger les
|
||
modeles.
|
||
</p>
|
||
<div class="config-row">
|
||
<label
|
||
class="config-label"
|
||
for="cfg-deepseek-key"
|
||
>DeepSeek API Key</label
|
||
>
|
||
<input
|
||
type="password"
|
||
id="cfg-deepseek-key"
|
||
class="config-input"
|
||
placeholder="sk-..."
|
||
autocomplete="off"
|
||
/>
|
||
<select
|
||
id="cfg-deepseek-model"
|
||
class="config-select"
|
||
style="width: 200px"
|
||
>
|
||
<option value="">-- Modele --</option>
|
||
</select>
|
||
</div>
|
||
<div class="config-row">
|
||
<label
|
||
class="config-label"
|
||
for="cfg-openrouter-key"
|
||
>OpenRouter API Key</label
|
||
>
|
||
<input
|
||
type="password"
|
||
id="cfg-openrouter-key"
|
||
class="config-input"
|
||
placeholder="sk-or-..."
|
||
autocomplete="off"
|
||
/>
|
||
<select
|
||
id="cfg-openrouter-model"
|
||
class="config-select"
|
||
style="width: 200px"
|
||
>
|
||
<option value="">-- Modele --</option>
|
||
</select>
|
||
</div>
|
||
<div class="config-row">
|
||
<label
|
||
class="config-label"
|
||
for="cfg-gemini-key"
|
||
>Gemini API Key</label
|
||
>
|
||
<input
|
||
type="password"
|
||
id="cfg-gemini-key"
|
||
class="config-input"
|
||
placeholder="AIza..."
|
||
autocomplete="off"
|
||
/>
|
||
<select
|
||
id="cfg-gemini-model"
|
||
class="config-select"
|
||
style="width: 200px"
|
||
>
|
||
<option value="">-- Modele --</option>
|
||
</select>
|
||
</div>
|
||
<div
|
||
class="config-actions-row"
|
||
style="margin-top: 16px"
|
||
>
|
||
<button class="config-btn-save"
|
||
id="cfg-save-ai-keys" data-i18n="help.shortcut_save">
|
||
><span data-i18n="sidebar.tab_backups">Sauvegardes</span>
|
||
</button>
|
||
<button class="config-btn-secondary"
|
||
id="cfg-test-ai-keys" data-i18n="config.test">
|
||
Tester
|
||
</button>
|
||
<span
|
||
id="cfg-ai-status"
|
||
style="
|
||
font-size: 12px;
|
||
color: var(--text-muted);
|
||
margin-left: 12px;
|
||
"
|
||
></span>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Themes -->
|
||
<section
|
||
class="config-section help-section"
|
||
id="cfg-themes"
|
||
>
|
||
<h2 data-i18n="auto.c14b5603">🎨 Thèmes</h2>
|
||
<p class="config-description" data-i18n="auto.caac40b9">
|
||
Choisissez un thème visuel. Chaque thème
|
||
offre un mode sombre et clair.
|
||
</p>
|
||
<div class="theme-grid" id="theme-grid">
|
||
<div class="config-diag-loading" data-i18n="common.loading">Chargement...</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Profil -->
|
||
<section
|
||
class="config-section help-section"
|
||
id="cfg-profile"
|
||
>
|
||
<h2 data-i18n="config.profile">👤 Profil utilisateur</h2>
|
||
<p class="config-description" data-i18n="config.profile_desc">
|
||
Préférences personnelles pour personnaliser
|
||
l'expérience ObsiGate.
|
||
</p>
|
||
<div class="profile-form" id="profile-form">
|
||
<div class="profile-field">
|
||
<label for="profile-lang" data-i18n="config.lang_label">Langue préférée</label>
|
||
<select id="profile-lang" class="config-select">
|
||
<option value="fr">Francais</option>
|
||
<option value="en">English</option>
|
||
<option value="es">Espanol</option>
|
||
<option value="de">Deutsch</option>
|
||
</select>
|
||
<span class="profile-hint" data-i18n="config.lang_hint">Utilisée par l'autocomplétion et le ghost text.</span>
|
||
</div>
|
||
<div class="profile-field">
|
||
<label for="profile-name" data-i18n="config.display_name">Nom d'affichage</label>
|
||
<input type="text" id="profile-name" class="config-input" placeholder="Votre nom" maxlength="60">
|
||
</div>
|
||
<button class="config-save-btn" id="profile-save" data-i18n="config.save">Enregistrer</button>
|
||
<button class="config-save-btn" id="profile-logout" style="background:var(--danger-bg);color:var(--danger);border-color:var(--danger);margin-left:8px" data-i18n="config.logout">Déconnexion</button>
|
||
<span class="profile-saved" id="profile-saved" style="display:none" data-i18n="config.saved">✓ Sauvegardé</span>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- À propos -->
|
||
<section
|
||
class="config-section help-section"
|
||
id="cfg-about"
|
||
>
|
||
<h2 data-i18n="auto.a3319169">📦 À propos</h2>
|
||
<div
|
||
id="config-about"
|
||
class="config-diagnostics"
|
||
>
|
||
<div class="config-diag-loading" data-i18n="common.loading">
|
||
Chargement...
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Webhooks -->
|
||
<section class="config-section help-section">
|
||
<h2>🔔 Webhooks</h2>
|
||
<p class="config-description">
|
||
Notifications HTTP vers des services
|
||
externes lors des changements de fichiers.
|
||
</p>
|
||
<div id="webhooks-list"></div>
|
||
<div class="config-add-row">
|
||
<input
|
||
type="text"
|
||
id="webhook-name-input"
|
||
data-i18n-placeholder="config.webhook_name_placeholder" placeholder="Nom"
|
||
class="config-input"
|
||
style="width: 100px"
|
||
/>
|
||
<input
|
||
type="text"
|
||
id="webhook-url-input"
|
||
placeholder="https://..."
|
||
class="config-input"
|
||
style="flex: 1"
|
||
/>
|
||
<button id="webhook-add-btn"
|
||
class="config-btn config-btn-add" data-i18n="config.add_webhook">
|
||
Ajouter
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Partages publics -->
|
||
<section class="config-section help-section">
|
||
<h2>📤 Partages publics</h2>
|
||
<p class="config-description">
|
||
Liens de partage publics pour des documents
|
||
(lecture seule, sans authentification).
|
||
</p>
|
||
<div id="shares-list"></div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Graph View Modal -->
|
||
<div class="editor-modal" id="graph-modal">
|
||
<div
|
||
class="editor-container"
|
||
style="
|
||
max-width: 95vw;
|
||
width: 1000px;
|
||
height: 85vh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
"
|
||
>
|
||
<!-- Header: 2 lignes — nav+titre+contrôles | recherche -->
|
||
<div
|
||
class="editor-header"
|
||
style="
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 6px;
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid var(--border-color);
|
||
"
|
||
>
|
||
<!-- Line 1: nav + title + controls -->
|
||
<div
|
||
style="
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
min-width: 0;
|
||
"
|
||
>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-nav-back"
|
||
title="Retour"
|
||
style="
|
||
font-size: 0.75rem;
|
||
padding: 2px 4px;
|
||
opacity: 0.3;
|
||
flex-shrink: 0;
|
||
min-width: 22px;
|
||
"
|
||
disabled
|
||
>
|
||
←
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-nav-fwd"
|
||
title="Avancer"
|
||
style="
|
||
font-size: 0.75rem;
|
||
padding: 2px 4px;
|
||
opacity: 0.3;
|
||
flex-shrink: 0;
|
||
min-width: 22px;
|
||
"
|
||
disabled
|
||
>
|
||
→
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-nav-up"
|
||
title="Dossier parent"
|
||
style="
|
||
font-size: 0.65rem;
|
||
padding: 2px 5px;
|
||
flex-shrink: 0;
|
||
display: none;
|
||
"
|
||
>
|
||
↑
|
||
</button>
|
||
<div
|
||
class="editor-title"
|
||
id="graph-title"
|
||
style="
|
||
font-weight: 600;
|
||
font-size: 0.85rem;
|
||
flex: 1;
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
"
|
||
>
|
||
Vue Graphique
|
||
</div>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-full-vault"
|
||
title="Vue complète du vault"
|
||
style="
|
||
font-size: 0.65rem;
|
||
padding: 3px 6px;
|
||
flex-shrink: 0;
|
||
"
|
||
>
|
||
🌐 Tout
|
||
</button>
|
||
<span
|
||
style="
|
||
font-size: 0.6rem;
|
||
color: var(--text-muted);
|
||
flex-shrink: 0;
|
||
"
|
||
>Prof.</span
|
||
>
|
||
<input
|
||
type="range"
|
||
id="graph-depth"
|
||
min="0"
|
||
max="3"
|
||
value="1"
|
||
style="width: 40px; flex-shrink: 0"
|
||
title="Profondeur"
|
||
/>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-zoom-out"
|
||
title="Zoom arrière"
|
||
style="flex-shrink: 0"
|
||
>
|
||
<i
|
||
data-lucide="zoom-out"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-zoom-in"
|
||
title="Zoom avant"
|
||
style="flex-shrink: 0"
|
||
>
|
||
<i
|
||
data-lucide="zoom-in"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-reset"
|
||
title="Réinitialiser"
|
||
style="flex-shrink: 0"
|
||
>
|
||
<i
|
||
data-lucide="maximize"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-export"
|
||
title="Exporter PNG"
|
||
style="flex-shrink: 0"
|
||
>
|
||
<i
|
||
data-lucide="download"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-fullscreen"
|
||
title="Plein écran"
|
||
style="flex-shrink: 0"
|
||
>
|
||
<i
|
||
data-lucide="expand"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="editor-btn"
|
||
id="graph-close"
|
||
title="Fermer"
|
||
style="flex-shrink: 0"
|
||
>
|
||
<i
|
||
data-lucide="x"
|
||
style="width: 15px; height: 15px"
|
||
></i>
|
||
</button>
|
||
</div>
|
||
<!-- Line 2: centered search -->
|
||
<div style="display: flex; justify-content: center">
|
||
<div
|
||
style="
|
||
position: relative;
|
||
width: 100%;
|
||
max-width: 450px;
|
||
"
|
||
>
|
||
<i
|
||
data-lucide="search"
|
||
style="
|
||
position: absolute;
|
||
left: 10px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 14px;
|
||
height: 14px;
|
||
color: var(--text-muted);
|
||
pointer-events: none;
|
||
"
|
||
></i>
|
||
<input
|
||
type="text"
|
||
id="graph-search"
|
||
placeholder="Rechercher ou #tag..."
|
||
style="
|
||
width: 100%;
|
||
font-size: 0.78rem;
|
||
padding: 5px 12px 5px 30px;
|
||
border-radius: 8px;
|
||
border: none;
|
||
background: var(--bg-secondary);
|
||
color: var(--text-primary);
|
||
outline: none;
|
||
box-shadow: inset 0 1px 3px
|
||
rgba(0, 0, 0, 0.2);
|
||
"
|
||
/>
|
||
<span
|
||
style="
|
||
position: absolute;
|
||
right: 10px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
font-size: 0.6rem;
|
||
color: var(--text-muted);
|
||
opacity: 0.4;
|
||
pointer-events: none;
|
||
"
|
||
>Ctrl+survol</span
|
||
>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div
|
||
class="editor-body"
|
||
style="
|
||
flex: 1;
|
||
overflow: hidden;
|
||
position: relative;
|
||
padding: 0;
|
||
"
|
||
>
|
||
<canvas
|
||
id="graph-canvas"
|
||
style="width: 100%; height: 100%; cursor: grab"
|
||
></canvas>
|
||
<!-- Info panel: top-right, shows on hover, stays until closed -->
|
||
<div
|
||
id="graph-info-panel"
|
||
style="
|
||
display: none;
|
||
position: absolute;
|
||
top: 10px;
|
||
left: 10px;
|
||
max-width: 320px;
|
||
background: var(--bg-primary);
|
||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||
border-radius: 8px;
|
||
padding: 12px 14px;
|
||
font-size: 0.78rem;
|
||
color: var(--text-primary);
|
||
z-index: 10;
|
||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
|
||
"
|
||
>
|
||
<button
|
||
id="graph-info-close"
|
||
style="
|
||
position: absolute;
|
||
top: 6px;
|
||
right: 8px;
|
||
background: none;
|
||
border: none;
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
font-size: 1rem;
|
||
line-height: 1;
|
||
padding: 2px;
|
||
"
|
||
title="Fermer"
|
||
>
|
||
✕
|
||
</button>
|
||
<div id="graph-info-content"></div>
|
||
</div>
|
||
<!-- Preview panel: right sidebar, full height, shows on Ctrl+hover, stays until closed -->
|
||
<div
|
||
id="graph-preview-panel"
|
||
style="
|
||
display: none;
|
||
position: absolute;
|
||
top: 0;
|
||
right: 0;
|
||
width: 380px;
|
||
height: 100%;
|
||
background: var(--bg-primary);
|
||
border-left: 1px solid var(--border-color);
|
||
z-index: 9;
|
||
overflow-y: auto;
|
||
font-size: 0.8rem;
|
||
color: var(--text-primary);
|
||
box-shadow: -4px 0 16px rgba(0, 0, 0, 0.3);
|
||
"
|
||
>
|
||
<button
|
||
id="graph-preview-close"
|
||
style="
|
||
position: sticky;
|
||
top: 0;
|
||
float: right;
|
||
background: var(--bg-primary);
|
||
border: 1px solid var(--border-color);
|
||
border-radius: 4px;
|
||
color: var(--text-muted);
|
||
cursor: pointer;
|
||
font-size: 0.9rem;
|
||
padding: 2px 8px;
|
||
z-index: 1;
|
||
margin-bottom: -24px;
|
||
"
|
||
title="Fermer"
|
||
>
|
||
✕ Fermer
|
||
</button>
|
||
<div
|
||
id="graph-preview-content"
|
||
style="padding: 16px; padding-top: 8px"
|
||
></div>
|
||
</div>
|
||
<!-- Status bar + legend -->
|
||
<div
|
||
style="
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 4px 12px;
|
||
background: var(--bg-primary);
|
||
border-top: 1px solid var(--border-color);
|
||
font-size: 0.7rem;
|
||
color: var(--text-muted);
|
||
"
|
||
>
|
||
<span id="graph-status">—</span>
|
||
<div
|
||
style="
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
"
|
||
>
|
||
<label
|
||
style="
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
"
|
||
><input
|
||
type="checkbox"
|
||
id="graph-filter-dir"
|
||
checked
|
||
/>
|
||
🟦 Dossier</label
|
||
>
|
||
<label
|
||
style="
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
"
|
||
><input
|
||
type="checkbox"
|
||
id="graph-filter-md"
|
||
checked
|
||
/>
|
||
🟩 .md</label
|
||
>
|
||
<label
|
||
style="
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 3px;
|
||
"
|
||
><input
|
||
type="checkbox"
|
||
id="graph-filter-other"
|
||
checked
|
||
/>
|
||
⬜ Autre</label
|
||
>
|
||
<span style="opacity: 0.5">│</span>
|
||
<span>── Parent</span>
|
||
<span style="color: var(--accent-color, #2563eb)"
|
||
>┅┅ Wikilink</span
|
||
>
|
||
<span style="color: #e74c3c">← Backlink</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Help Modal -->
|
||
<div class="editor-modal" id="help-modal">
|
||
<div class="editor-container help-container">
|
||
<div class="editor-header">
|
||
<button
|
||
class="help-hamburger"
|
||
id="help-hamburger"
|
||
title="Sommaire"
|
||
aria-label="Afficher le sommaire"
|
||
onclick="
|
||
var n = document.getElementById('help-nav');
|
||
if (n) {
|
||
var d = n.style.display;
|
||
n.style.display =
|
||
d === 'none' || d === '' ? 'flex' : 'none';
|
||
}
|
||
"
|
||
>
|
||
<i
|
||
data-lucide="menu"
|
||
style="width: 18px; height: 18px"
|
||
></i>
|
||
</button>
|
||
<div class="editor-title" id="help-title" data-i18n="help.modal_title">
|
||
Guide d'utilisation ObsiGate
|
||
</div>
|
||
<div class="editor-actions">
|
||
<button
|
||
class="editor-btn"
|
||
id="help-close"
|
||
title="Fermer l'aide" data-i18n-attr="title:help.close_help"
|
||
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-header">
|
||
<div class="help-nav-title" data-i18n="help.toc_title">Sommaire</div>
|
||
</div>
|
||
<div class="help-nav-search-wrap">
|
||
<input
|
||
type="text"
|
||
class="help-nav-search"
|
||
id="help-nav-search"
|
||
data-i18n-placeholder="help.search_placeholder" data-i18n-placeholder="help.search_placeholder" placeholder="Rechercher dans l'aide..."
|
||
autocomplete="off"
|
||
spellcheck="false"
|
||
/>
|
||
<button
|
||
class="help-search-clear"
|
||
id="help-search-clear"
|
||
title="Effacer la recherche"
|
||
aria-label="Effacer"
|
||
onclick="
|
||
var s =
|
||
document.getElementById(
|
||
'help-nav-search',
|
||
);
|
||
if (s) {
|
||
s.value = '';
|
||
s.dispatchEvent(new Event('input'));
|
||
s.focus();
|
||
}
|
||
"
|
||
>
|
||
✕
|
||
</button>
|
||
</div>
|
||
<ul class="help-nav-list" id="help-nav-list">
|
||
<li>
|
||
<a href="#help-intro" class="help-nav-link"
|
||
data-i18n="help.nav_intro">📘 Introduction</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-interface" class="help-nav-link"
|
||
data-i18n="help.nav_interface">🧭 Interface</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-navigation" class="help-nav-link"
|
||
data-i18n="help.nav_navigation">🗺️ Navigation</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-tabs" class="help-nav-link"
|
||
data-i18n="help.nav_tabs">📑 Onglets</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-recherche" class="help-nav-link"
|
||
data-i18n="help.nav_search">🔍 Recherche</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-tags" class="help-nav-link"
|
||
data-i18n="help.nav_tags">🏷️ Tags</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-fichiers" class="help-nav-link"
|
||
data-i18n="help.nav_files">📁 Fichiers</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-edition" class="help-nav-link"
|
||
data-i18n="help.nav_editing">✏️ Édition</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-graphe" class="help-nav-link"
|
||
data-i18n="help.nav_graph">🗺️ Graphe</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-ai" class="help-nav-link"
|
||
data-i18n="help.nav_ai">🤖 IA Éditeur</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-palette" class="help-nav-link"
|
||
data-i18n="help.nav_palette">⌨️ Palette</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-raccourcis" class="help-nav-link"
|
||
data-i18n="help.nav_shortcuts">⌨️ Raccourcis</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-partage" class="help-nav-link"
|
||
data-i18n="help.nav_sharing">🔗 Partage</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-webhooks" class="help-nav-link"
|
||
data-i18n="help.nav_webhooks">🪝 Webhooks</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a
|
||
href="#help-sauvegardes"
|
||
class="help-nav-link"
|
||
data-i18n="help.nav_backups">💾 Sauvegardes</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-securite" class="help-nav-link"
|
||
data-i18n="help.nav_security">🛡️ Sécurité</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a
|
||
href="#help-personnalisation"
|
||
class="help-nav-link"
|
||
data-i18n="help.nav_customization">🎨 Personnalisation</a
|
||
>
|
||
</li>
|
||
<li>
|
||
<a href="#help-astuces" class="help-nav-link"
|
||
data-i18n="help.nav_tips">💡 Astuces</a
|
||
>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
<div class="help-content">
|
||
<section class="help-section help-hero" id="help-intro">
|
||
<div class="help-hero-copy">
|
||
<div class="help-kicker" data-i18n="help.guide_official">Guide officiel</div>
|
||
<h1 data-i18n="help.welcome_title">📘 Bienvenue dans ObsiGate</h1>
|
||
<p class="help-lead" data-i18n="auto.6c166d35">
|
||
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" data-i18n="help.welcome_tag1"
|
||
>⚡ Navigation rapide</span
|
||
>
|
||
<span class="help-badge" data-i18n="help.welcome_tag2"
|
||
>🗂️ Multi-vault</span
|
||
>
|
||
<span class="help-badge" data-i18n="help.welcome_tag3"
|
||
>🏷️ Tags intelligents</span
|
||
>
|
||
<span class="help-badge" data-i18n="help.welcome_tag4"
|
||
>📝 Lecture et édition</span
|
||
>
|
||
<span class="help-badge" data-i18n="help.welcome_tag5"
|
||
>🔍 Recherche TF-IDF</span
|
||
>
|
||
</div>
|
||
</div>
|
||
<div class="help-hero-visual" aria-hidden="true">
|
||
<div class="help-stat-card">
|
||
<span class="help-stat-label" data-i18n="help.experience"
|
||
>Expérience</span
|
||
>
|
||
<strong data-i18n="help.simple">Simple</strong>
|
||
</div>
|
||
<div class="help-stat-card">
|
||
<span class="help-stat-label" data-i18n="help.search_bar"
|
||
>Recherche</span
|
||
>
|
||
<strong data-i18n="help.instant">Instantanée</strong>
|
||
</div>
|
||
<div class="help-stat-card">
|
||
<span class="help-stat-label" data-i18n="help.access"
|
||
>Accès</span
|
||
>
|
||
<strong data-i18n="help.multi_vault">Multi-vault</strong>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-interface">
|
||
<h2 data-i18n="help.nav_interface">🧭 Interface utilisateur</h2>
|
||
|
||
<h3 data-i18n="help.header_section">En-tête</h3>
|
||
<p data-i18n="auto.209c5490">
|
||
La barre supérieure contient les éléments
|
||
essentiels :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.hamburger_btn">Bouton menu hamburger</strong>
|
||
: <span data-i18n="help.desc_hamburger">obile) : Affiche/masque la sidebar</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.sidebar_toggle_btn">Bouton toggle sidebar</strong> <span data-i18n="help.desc_sidebar_toggle">(desktop) : Masque la sidebar pour plus
|
||
d'espace</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.logo">Logo ObsiGate</strong> <span data-i18n="help.desc_logo">: Retour à
|
||
l'accueil</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.search_bar">Barre de recherche</strong> <span data-i18n="help.desc_search_bar">:
|
||
Recherche globale avec autocomplétion</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.vault_indicator">Indicateur de vault</strong> <span data-i18n="help.desc_vault_indicator">:
|
||
Affiche le contexte actif (All, vault1,
|
||
etc.)</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.menu_options">Menu Options</strong> <span data-i18n="help.desc_menu_options">: Accès aux
|
||
paramètres, thème, aide</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.sidebar_section">Sidebar (barre latérale)</h3>
|
||
<p data-i18n="help.sidebar_tabs">La sidebar est divisée en deux onglets :</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="sidebar.tab_vaults">Vaults</strong> <span data-i18n="help.desc_vaults_tab">: Arborescence des
|
||
fichiers et dossiers</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="sidebar.tab_tags">Tags</strong> <span data-i18n="help.desc_tags_tab">: Nuage de tags
|
||
cliquables</span>
|
||
</li>
|
||
</ul>
|
||
<p data-i18n="help.sidebar_features">Fonctionnalités de la sidebar :</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.filtering">Filtrage</strong> <span data-i18n="help.desc_filtering">: Barre de
|
||
recherche pour filtrer fichiers/tags</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.quick_select">Sélection rapide</strong> <span data-i18n="help.desc_quick_select">: Dropdown
|
||
pour changer de vault</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.resize">Redimensionnement</strong> <span data-i18n="help.desc_resize">: Glissez
|
||
le bord droit pour ajuster la largeur</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.hide">Masquage</strong> <span data-i18n="help.desc_hide">: Cliquez sur
|
||
l'icône sidebar dans le header</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.content_area">Zone de contenu</h3>
|
||
<p data-i18n="help.content_shows">La zone centrale affiche :</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.breadcrumb">Breadcrumb</strong> <span data-i18n="help.desc_breadcrumb">: Chemin du
|
||
fichier (cliquable pour repositionner la
|
||
sidebar)</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.title_tags">Titre et tags</strong> <span data-i18n="help.desc_title_tags">: Métadonnées
|
||
du fichier</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.action_buttons">Boutons d'action</strong> <span data-i18n="help.desc_action_buttons">: Copier,
|
||
Source, Télécharger, Éditer, Ouvrir dans
|
||
nouvelle fenêtre</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.rendered_content">Contenu rendu</strong> <span data-i18n="help.desc_rendered_content">: Markdown
|
||
avec wikilinks et images</span>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-navigation">
|
||
<h2 data-i18n="help.733f0559">🗺️ Navigation</h2>
|
||
|
||
<h3 data-i18n="help.tree_section">Arborescence des vaults</h3>
|
||
<p data-i18n="auto.4c908ade">
|
||
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 data-i18n="sidebar.expand_collapse">Développer/Réduire</strong><span data-i18n="help.desc_expand">:
|
||
Cliquez sur un dossier</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="sidebar.open_file">Ouvrir un fichier</strong><span data-i18n="help.desc_open_file">: Cliquez
|
||
sur le nom du fichier</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="sidebar.file_icons">Icônes</strong><span data-i18n="help.desc_fdeaf803"> : Chaque type de
|
||
fichier a son icône (markdown, code, etc.)</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.sidebar_filtering">Filtrage de la sidebar</h3>
|
||
<p data-i18n="help.desc_filter_usage">
|
||
Utilisez la barre de filtrage en haut de la
|
||
sidebar pour rechercher rapidement :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="sidebar.filter_instant">Recherche instantanée</strong><span data-i18n="help.desc_instant_filter">:
|
||
Tapez pour filtrer fichiers et dossiers</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.case_sensitive">Case-sensitive</strong><span data-i18n="help.desc_case_sensitive">: Bouton
|
||
"Aa" pour respecter la casse</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.clear">Effacer</strong><span data-i18n="help.desc_a4a4e21b"> : Bouton "×" pour
|
||
réinitialiser le filtre</span></li>
|
||
<li>
|
||
<strong data-i18n="help.results_grouped">Résultats groupés</strong><span data-i18n="help.desc_grouped_results">:
|
||
Affichage par vault avec chemins complets</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.breadcrumb_reposition">Breadcrumb et repositionnement</h3>
|
||
<p data-i18n="auto.1abf6661">
|
||
Le chemin affiché au-dessus du contenu est
|
||
interactif :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.click_vault">Cliquez sur le vault</strong><span data-i18n="help.desc_click_vault">:
|
||
Focus sur le vault dans la sidebar</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.click_segment">Cliquez sur un segment</strong><span data-i18n="help.desc_click_segment">:
|
||
Navigation vers ce dossier</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.auto_scroll">Auto-scroll</strong><span data-i18n="help.desc_autoscroll">: La sidebar se
|
||
positionne automatiquement</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.vault_selector">Sélection de vault</h3>
|
||
<p data-i18n="help.desc_vault_context">
|
||
Changez de contexte pour filtrer l'affichage :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.menu_header">Menu header</strong><span data-i18n="help.desc_menu_header">: Dropdown
|
||
"Vault" dans le menu Options</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.sidebar_dropdown">Sidebar dropdown</strong><span data-i18n="help.desc_085ec31f"> :
|
||
Sélection rapide en haut de l'onglet Vaults</span></li>
|
||
<li>
|
||
<strong data-i18n="help.all_vaults">Tous les vaults</strong><span data-i18n="help.desc_all_vaults">: Vue
|
||
globale de tous vos contenus</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.vault_specific">Vault spécifique</strong><span data-i18n="help.desc_specific_vault">: Focus
|
||
sur un seul vault</span>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-tabs">
|
||
<h2 data-i18n="help.8c5341e0">📑 Gestion des onglets</h2>
|
||
<p data-i18n="auto.27a2f7c1">
|
||
ObsiGate supporte l'ouverture de plusieurs
|
||
fichiers simultanément dans des onglets.
|
||
</p>
|
||
|
||
<h3 data-i18n="help.tabs_section">Ouverture d'onglets</h3>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.single_click">Simple clic</strong><span data-i18n="help.desc_e3fce7a3"> : Ouvre le
|
||
fichier dans un onglet temporaire (aperçu,
|
||
italique)</span></li>
|
||
<li>
|
||
<strong data-i18n="help.double_click">Double clic</strong><span data-i18n="help.desc_double_click">: Ouvre le
|
||
fichier dans un onglet persistant</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.recent_nav">Navigation récente</strong><span data-i18n="help.desc_d186a19e"> :
|
||
L'onglet "Récent" dans la sidebar liste vos
|
||
derniers fichiers</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.tab_nav">Navigation entre onglets</h3>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.click_tab">Clic sur un onglet</strong><span data-i18n="help.desc_click_tab">: Active
|
||
l'onglet</span>
|
||
</li>
|
||
<li>
|
||
<strong>Ctrl+Tab</strong><span data-i18n="help.desc_ctrl_tab">: Onglet suivant</span>
|
||
</li>
|
||
<li>
|
||
<strong>Ctrl+Shift+Tab</strong><span data-i18n="help.desc_e5246734"> : Onglet
|
||
précédent</span></li>
|
||
<li>
|
||
<strong>Ctrl+W</strong><span data-i18n="help.desc_ctrl_w">: Fermer l'onglet
|
||
actif</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.close_tab_x">Bouton ✕</strong><span data-i18n="help.desc_close_btn">: Ferme l'onglet
|
||
(sauf s'il est seul)</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.tab_features">Fonctionnalités</h3>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.tab_bar">Barre d'onglets</strong><span data-i18n="help.desc_170a6982"> : Affichage
|
||
horizontal avec le nom du fichier et son
|
||
icône</span></li>
|
||
<li>
|
||
<strong data-i18n="help.active_tab">Onglet actif</strong><span data-i18n="help.desc_6b649b1e"> : Surligné en
|
||
couleur d'accentuation</span></li>
|
||
<li>
|
||
<strong data-i18n="help.preview_tab">Prévisualisation</strong><span data-i18n="help.desc_ef1531ce"> : Un
|
||
onglet temporaire (italique) est remplacé
|
||
par le prochain clic</span></li>
|
||
<li>
|
||
<strong data-i18n="help.persistent_tabs">Onglets persistants</strong><span data-i18n="help.desc_5ab8c78d"> :
|
||
Restent ouverts jusqu'à fermeture manuelle</span></li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-recherche">
|
||
<h2 data-i18n="help.adf30d78">🔍 Recherche</h2>
|
||
|
||
<h3 data-i18n="help.simple_search">Recherche simple</h3>
|
||
<p data-i18n="help.desc_search_intro">
|
||
Tapez dans la barre de recherche en haut pour
|
||
lancer une recherche fulltext :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="search.full_text">Recherche dans tout</strong><span data-i18n="help.desc_search_all">:
|
||
Titre, contenu, tags, chemins</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.smart_scoring">Scoring intelligent</strong><span data-i18n="help.desc_00b9572b"> :
|
||
Résultats classés par pertinence TF-IDF</span></li>
|
||
<li>
|
||
<strong data-i18n="help.highlighted_snippets">Snippets surlignés</strong><span data-i18n="help.desc_snippets">:
|
||
Extraits avec termes en surbrillance</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.pagination">Pagination</strong><span data-i18n="help.desc_53bfaeca"> : Navigation par
|
||
pages de 50 résultats</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.advanced_operators">Opérateurs avancés</h3>
|
||
<p data-i18n="auto.4bc1f00a">
|
||
Utilisez des opérateurs pour affiner votre
|
||
recherche :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<span data-i18n="help.desc_op_tag"><code>tag:docker</code> ou
|
||
<code>#docker</code> : Filtrer par tag</span>
|
||
</li>
|
||
<li>
|
||
<span data-i18n="help.desc_op_vault"><code>vault:IT</code> : Rechercher dans un
|
||
vault spécifique</span>
|
||
</li>
|
||
<li>
|
||
<span data-i18n="help.desc_op_title"><code>title:kubernetes</code> : Chercher
|
||
dans les titres uniquement</span>
|
||
</li>
|
||
<li>
|
||
<span data-i18n="help.desc_op_path"><code>path:recettes/soupes</code> : Filtrer
|
||
par chemin</span>
|
||
</li>
|
||
<li>
|
||
<span data-i18n="help.desc_op_ext"><code>ext:md</code> : Filtrer par type de
|
||
fichier</span>
|
||
</li>
|
||
<li>
|
||
<span data-i18n="help.desc_op_phrase"><code>"phrase exacte"</code> : Recherche de
|
||
phrase entre guillemets</span>
|
||
</li>
|
||
</ul>
|
||
<p>
|
||
<strong>Exemples</strong><span data-i18n="help.desc_examples">:
|
||
<code>ext:sh</code> recherche dans les scripts
|
||
bash, <code>ext:py</code> dans les scripts
|
||
Python, <code>ext:md</code> dans les fichiers
|
||
Markdown.
|
||
</p></span>
|
||
<p>
|
||
<strong data-i18n="auto.1a54bd69">Exemple combiné</strong> :
|
||
<code
|
||
>tag:linux vault:IT ext:md serveur web</code
|
||
>
|
||
<span data-i18n="help.desc_combined">recherche "serveur web" dans les fichiers
|
||
Markdown du vault IT avec le tag linux.</span>
|
||
</p>
|
||
|
||
<h3 data-i18n="help.autocomplete">Autocomplétion</h3>
|
||
<p data-i18n="auto.404c8f1c">
|
||
L'autocomplétion vous aide à trouver rapidement
|
||
:
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="search.dropdown_history">Historique</strong><span data-i18n="help.desc_4de7e318"> : Les 50
|
||
dernières recherches (localStorage)</span></li>
|
||
<li>
|
||
<strong data-i18n="palette.mode_files">Fichiers</strong><span data-i18n="help.desc_file_suggest">: Suggestions de
|
||
titres de fichiers</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="sidebar.tab_tags">Tags</strong><span data-i18n="help.desc_tag_suggest">: Suggestions de tags
|
||
avec compteurs</span>
|
||
</li>
|
||
<li>
|
||
<strong>Navigation clavier</strong><span data-i18n="help.desc_6b8fc728"> : ↑/↓
|
||
pour naviguer, Enter pour sélectionner</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.active_filter_chips">Chips de filtres actifs</h3>
|
||
<p data-i18n="auto.03a6e5b1">
|
||
Les opérateurs utilisés s'affichent sous forme
|
||
de chips colorés :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Visualisation</strong><span data-i18n="help.desc_chip_view">: Voir d'un
|
||
coup d'œil les filtres actifs</span>
|
||
</li>
|
||
<li>
|
||
<strong>Suppression</strong><span data-i18n="help.desc_chip_remove">: Cliquez sur
|
||
"×" pour retirer un filtre</span>
|
||
</li>
|
||
<li>
|
||
<strong>Couleurs</strong><span data-i18n="help.desc_6ebebdfd"> : Chaque type
|
||
d'opérateur a sa couleur</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.a648c49e">Facettes et tri</h3>
|
||
<p data-i18n="auto.cd7332c8">
|
||
Les résultats incluent des facettes pour affiner
|
||
:
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Facettes tags</strong><span data-i18n="help.desc_cf5ccd40"> : Compteurs
|
||
par tag dans les résultats</span></li>
|
||
<li>
|
||
<strong>Facettes vaults</strong><span data-i18n="help.desc_facet_vaults">: Compteurs
|
||
par vault</span>
|
||
</li>
|
||
<li>
|
||
<strong>Tri par pertinence</strong><span data-i18n="help.desc_9fec424d"> : Score
|
||
TF-IDF (défaut)</span></li>
|
||
<li>
|
||
<strong>Tri par date</strong><span data-i18n="help.desc_42a81347"> : Dernière
|
||
modification</span></li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-tags">
|
||
<h2 data-i18n="help.2507242f">🏷️ Tags</h2>
|
||
|
||
<h3 data-i18n="help.5f87ea79">Tag cloud</h3>
|
||
<p data-i18n="help.desc_tag_cloud_intro">
|
||
L'onglet Tags de la sidebar affiche un nuage de
|
||
tags :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Tous les tags</strong><span data-i18n="help.desc_all_tags">: Extraits
|
||
des frontmatters YAML et inline (#tag)</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.clickable">Cliquable</strong><span data-i18n="help.desc_6caffeed"> : Cliquez pour
|
||
filtrer les résultats</span></li>
|
||
<li>
|
||
<strong data-i18n="help.filtering">Filtrage</strong><span data-i18n="help.desc_tag_filter_use">: Utilisez la
|
||
barre de filtrage pour chercher un tag</span>
|
||
</li>
|
||
<li>
|
||
<strong>Contexte vault</strong><span data-i18n="help.desc_6a5ddef2"> : Les tags
|
||
s'adaptent au vault sélectionné</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.2c03a7ba">Tags inline vs frontmatter</h3>
|
||
<p data-i18n="help.desc_two_tag_types">ObsiGate supporte deux types de tags :</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Frontmatter YAML</strong><span data-i18n="help.desc_frontmatter">:
|
||
<code>tags: [docker, linux]</code> ou
|
||
<code>tags: docker, linux</code></span>
|
||
</li>
|
||
<li>
|
||
<strong>Inline</strong><span data-i18n="help.desc_inline_tags">:
|
||
<code>#docker</code> dans le contenu
|
||
markdown</span>
|
||
</li>
|
||
<li>
|
||
<strong>Fusion automatique</strong><span data-i18n="help.desc_828db5da"> : Les
|
||
deux types sont combinés</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.63f024d4">Filtrage de tags template</h3>
|
||
<p data-i18n="help.desc_template_intro">
|
||
Dans les Configurations, vous pouvez masquer les
|
||
tags de template :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Patterns wildcards</strong><span data-i18n="help.desc_patterns">: Ex:
|
||
<code>#<% ... %></code> ou
|
||
<code>#{{ ... }}</code></span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="auto.5d936af6">Regex générée</strong><span data-i18n="help.desc_b9c94994"> : Aperçu de
|
||
la regex appliquée</span></li>
|
||
<li>
|
||
<strong data-i18n="help.add_remove">Ajout/Suppression</strong><span data-i18n="help.desc_ef3f8158"> : Gérez
|
||
vos patterns de filtrage</span></li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-fichiers">
|
||
<h2 data-i18n="help.c017944b">📄 Fichiers</h2>
|
||
|
||
<h3 data-i18n="help.cf8615b1">Visualisation</h3>
|
||
<p data-i18n="help.desc_md_render">Les fichiers markdown sont rendus avec :</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Wikilinks cliquables</strong><span data-i18n="help.desc_wikilinks">:
|
||
<code>[[lien]]</code> et
|
||
<code>[[lien|texte]]</code></span>
|
||
</li>
|
||
<li>
|
||
<strong>Images Obsidian</strong><span data-i18n="help.desc_images">: Support
|
||
de <code>![[image.png]]</code></span>
|
||
</li>
|
||
<li>
|
||
<strong>Syntax highlighting</strong><span data-i18n="help.desc_syntax_hl">:
|
||
Coloration des blocs de code</span>
|
||
</li>
|
||
<li>
|
||
<strong>Tables, listes, quotes</strong><span data-i18n="help.desc_markdown_all">:
|
||
Rendu complet du markdown</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.context_actions">Actions sur fichiers</h3>
|
||
<p data-i18n="help.actions_detail">Boutons disponibles au-dessus du contenu :</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="viewer.copy">Copier</strong><span data-i18n="help.desc_copy_btn">: Copie le contenu
|
||
source dans le presse-papiers</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="viewer.source">Source</strong><span data-i18n="help.desc_source_btn">: Affiche/masque le
|
||
markdown brut</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="viewer.download">Télécharger</strong><span data-i18n="help.desc_a52fc3b1"> : Télécharge le
|
||
fichier</span></li>
|
||
<li>
|
||
<strong data-i18n="viewer.edit">Éditer</strong><span data-i18n="help.desc_995a711f"> : Ouvre l'éditeur
|
||
CodeMirror</span></li>
|
||
<li>
|
||
<strong
|
||
>Ouvrir dans nouvelle fenêtre</strong
|
||
><span data-i18n="help.desc_open_new">: Ouvre le fichier dans un nouvel onglet</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="auto.1efbbc9a">Édition avec CodeMirror 6</h3>
|
||
<p data-i18n="auto.edf89626">L'éditeur intégré offre :</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Coloration syntaxique</strong><span data-i18n="help.desc_cm_syntax">:
|
||
Support de nombreux langages</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="auto.1d46301c">Numéros de ligne</strong><span data-i18n="help.desc_cm_lines">:
|
||
Navigation facile</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.autocomplete">Autocomplétion</strong><span data-i18n="help.desc_cm_autocomplete">:
|
||
Suggestions contextuelles</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="settings.search">Recherche</strong><span data-i18n="help.desc_cm_search">: Ctrl+F pour
|
||
chercher dans le fichier</span>
|
||
</li>
|
||
<li>
|
||
<strong>Sauvegarde</strong><span data-i18n="help.desc_save_btn_new">: Bouton ✓ pour
|
||
enregistrer</span>
|
||
</li>
|
||
<li>
|
||
<strong>Suppression</strong><span data-i18n="help.desc_delete_btn_new">: Bouton
|
||
corbeille pour supprimer</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="auto.ec7260fa">Types de fichiers supportés</h3>
|
||
<p data-i18n="help.indexes">ObsiGate indexe et affiche :</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="viewer.markdown">Markdown</strong> : .md (rendu
|
||
complet)
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="mermaid.code">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 data-i18n="help.other">Autres</strong> : .txt, .log, .sql,
|
||
.csv
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- ✏️ Édition -->
|
||
<section class="help-section" id="help-edition">
|
||
<h2 data-i18n="auto.f346076a">✏️ Édition avancée</h2>
|
||
|
||
<h3 data-i18n="auto.695d9e47">Éditeur CodeMirror 6</h3>
|
||
<p data-i18n="auto.ef8c5f4d">
|
||
L'éditeur intégré offre une expérience complète
|
||
d'édition :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong>Coloration syntaxique</strong><span data-i18n="help.desc_adv_syntax">:
|
||
Python, JS, HTML, CSS, Java, C++, Rust, Go
|
||
et bien d'autres</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="auto.1d46301c">Numéros de ligne</strong><span data-i18n="help.desc_9f78b3ec"> :
|
||
Navigation facilitée dans les fichiers longs</span></li>
|
||
<li>
|
||
<strong>Find in page</strong><span data-i18n="help.desc_find_in_page">: Ctrl+F pour
|
||
chercher dans le fichier (casse, regex, mot
|
||
entier)</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.auto_save">Sauvegarde automatique</strong><span data-i18n="help.desc_065f53ee"> :
|
||
Auto-save silencieux après 2s d'inactivité,
|
||
flash vert de confirmation</span></li>
|
||
<li>
|
||
<strong>Bouton ✓</strong><span data-i18n="help.desc_check_btn">: Sauvegarde
|
||
manuelle</span>
|
||
</li>
|
||
<li>
|
||
<strong>Bouton 🗑️</strong><span data-i18n="help.desc_trash_btn">: Suppression du
|
||
fichier</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.toolbar_section">Barre d'outils AI</strong><span data-i18n="help.desc_c8532869"> :
|
||
Complétion, réécriture, traduction (voir
|
||
section</span><a href="#help-ai" data-i18n="settings.ai">🤖 IA</a>)
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- 🗺️ Graphe -->
|
||
<section class="help-section" id="help-graphe">
|
||
<h2 data-i18n="help.9c7a0a8d">🗺️ Vue Graphe</h2>
|
||
<p data-i18n="help.desc_graph_intro">
|
||
La vue graphe offre une visualisation
|
||
interactive des connexions entre vos notes via
|
||
les wikilinks.
|
||
</p>
|
||
|
||
<h3 data-i18n="help.b6619ac9">Ouverture</h3>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.graph_context">Menu contextuel</strong><span data-i18n="help.desc_context_menu">: Clic
|
||
droit sur un vault ou dossier → Vue
|
||
Graphique</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.popout_button">Bouton dédié</strong><span data-i18n="help.desc_e23c94dd"> : Dans la
|
||
barre d'outils (le cas échéant)</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.61ee5a22">Interaction</h3>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.graph_zoom">Zoom/Pan</strong><span data-i18n="help.desc_f0adf67a"> : Molette pour
|
||
zoomer, cliquer-glisser pour se déplacer</span></li>
|
||
<li>
|
||
<strong data-i18n="help.graph_depth">Slider de profondeur</strong><span data-i18n="help.desc_9edeaa11"> :
|
||
Contrôle la profondeur d'exploration (0-3)</span></li>
|
||
<li>
|
||
<strong data-i18n="help.graph_tag_filter">Filtre par tag</strong><span data-i18n="help.desc_89bd3c4c"> : N'affiche
|
||
que les nœuds avec un tag spécifique</span></li>
|
||
<li>
|
||
<strong data-i18n="help.graph_type_filter">Filtre par type</strong><span data-i18n="help.desc_filter_type">:
|
||
Inclut/exclut fichiers, dossiers, markdown,
|
||
autres</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.graph_visual">Recherche visuelle</strong><span data-i18n="help.desc_visual_search">: Barre
|
||
de recherche pour surligner des nœuds</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.graph_focus">Mode focus</strong><span data-i18n="help.desc_a9db82b5"> : Centre la vue
|
||
sur un nœud spécifique</span></li>
|
||
<li>
|
||
<strong data-i18n="help.graph_nav_arrows">Navigation ← → ↑</strong><span data-i18n="help.desc_graph_nav">:
|
||
Historique de navigation entre les nœuds</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.8caed987">Affichage</h3>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.graph_nodes">Nœuds</strong><span data-i18n="help.desc_ab2c4150"> : Fichiers (carrés)
|
||
et dossiers (cercles) avec icônes</span></li>
|
||
<li>
|
||
<strong data-i18n="help.nodes_edges">Arêtes</strong><span data-i18n="help.desc_edges">: Wikilinks sortants
|
||
(bleu) et backlinks entrants (vert)</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.graph_info">Panneau d'info</strong><span data-i18n="help.desc_8717768b"> :
|
||
Métadonnées du nœud (tags, liens, chemin)</span></li>
|
||
<li>
|
||
<strong data-i18n="help.graph_preview">Ctrl+survol</strong><span data-i18n="help.desc_a579cf4d"> : Aperçu du
|
||
contenu de la note sans naviguer</span></li>
|
||
<li>
|
||
<strong data-i18n="graph.fullscreen">Plein écran</strong><span data-i18n="help.desc_fullscreen">: Bouton pour
|
||
agrandir la vue</span>
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="help.graph_export">Export PNG</strong><span data-i18n="help.desc_export_png">: Sauvegardez le
|
||
graphe en image</span>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="config.section_perf">Performance</h3>
|
||
<p data-i18n="auto.aa8ca265">
|
||
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>
|
||
|
||
|
||
|
||
<!-- ⌨️ Palette de commandes -->
|
||
<section class="help-section" id="help-ai">
|
||
<h2 data-i18n="auto.c4922a99">🤖 Intelligence Artificielle dans l'Éditeur</h2>
|
||
<p data-i18n="help.desc_b5f89b3b">
|
||
ObsiGate intègre un assistant IA directement
|
||
dans l'éditeur de texte. Pour l'activer,
|
||
configurez au moins un provider AI dans le
|
||
fichier <code>.env</code> (DeepSeek, OpenRouter
|
||
ou Gemini).
|
||
</p>
|
||
|
||
<h3 data-i18n="help.activation">Activation</h3>
|
||
<ol>
|
||
<li data-i18n="help.desc_f53badcd">
|
||
Ajoutez votre clé API dans
|
||
<code>.env</code> :
|
||
<code>DEEPSEEK_API_KEY=sk-...</code>
|
||
</li>
|
||
<li data-i18n="help.desc_ba4578ae">
|
||
Redémarrez le conteneur :
|
||
<code
|
||
>docker compose down && docker compose
|
||
up -d --build</code
|
||
>
|
||
</li>
|
||
<li data-i18n="auto.5d4a2516">
|
||
Ouvrez un fichier en mode Édition (bouton ✏️
|
||
Éditer)
|
||
</li>
|
||
<li data-i18n="auto.396d0dd8">
|
||
La barre d'outils AI apparaît sous le titre
|
||
de l'éditeur
|
||
</li>
|
||
</ol>
|
||
|
||
<h3 data-i18n="help.toolbar_section">Barre d'outils AI</h3>
|
||
<p data-i18n="help.desc_803161e5">
|
||
La barre d'outils contient les boutons suivants
|
||
:
|
||
</p>
|
||
<ul>
|
||
<li data-i18n="help.desc_e0525213">
|
||
<strong>✦ AI</strong><span data-i18n="help.desc_3ace259e"> — Complétion inline
|
||
(</span><kbd>Ctrl+J</kbd>). <span data-i18n="help.ai_completes">Complète</span>
|
||
automatiquement le texte là où se trouve le
|
||
curseur.
|
||
</li>
|
||
<li data-i18n="help.desc_11cf9e8a">
|
||
<strong data-i18n="auto.a105a2d9">Éditer ▾</strong><span data-i18n="help.desc_a0ec890a"> — Menu de
|
||
modification du texte sélectionné :</span><ul>
|
||
<li>
|
||
🪄
|
||
<strong>Improve writing</strong> :
|
||
Améliore la qualité, la clarté et le
|
||
flux du texte
|
||
</li>
|
||
<li data-i18n="help.desc_a6cb3b26">
|
||
🔤
|
||
<strong
|
||
>Fix spelling & grammar</strong
|
||
>
|
||
: Corrige les fautes d'orthographe
|
||
et de grammaire
|
||
</li>
|
||
<li data-i18n="help.desc_5a53de53">
|
||
📏 <strong>Make shorter</strong> :
|
||
Rend le texte plus concis tout en
|
||
préservant l'information
|
||
</li>
|
||
<li data-i18n="help.desc_e36f3eaa">
|
||
📐 <strong>Make longer</strong> :
|
||
Ajoute des détails, exemples ou
|
||
explications
|
||
</li>
|
||
<li data-i18n="help.desc_3d4e9189">
|
||
📋
|
||
<strong>Simplify language</strong> :
|
||
Simplifie le langage, évite le
|
||
jargon
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li data-i18n="help.desc_5524e921">
|
||
<strong>Ton ▾</strong> — Change le ton du
|
||
texte :
|
||
<ul>
|
||
<li>
|
||
💼 <strong>Professional</strong> :
|
||
Ton formel et professionnel
|
||
</li>
|
||
<li data-i18n="help.desc_759926ee">
|
||
💬 <strong>Casual</strong> : <span data-i18n="help.ai_tone_casual">Ton</span>
|
||
décontracté et conversationnel
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li data-i18n="help.desc_7ab5be50">
|
||
<strong>Traduire ▾</strong><span data-i18n="help.desc_1c130d89"> — Traduit le
|
||
texte sélectionné vers une autre langue :</span><ul>
|
||
<li>
|
||
🇬🇧 English · 🇨🇳 Chinese · 🇯🇵
|
||
Japanese · 🇩🇪 German · 🇫🇷 French ·
|
||
🇪🇸 Spanish
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li data-i18n="help.desc_47e1e10f">
|
||
<strong data-i18n="auto.ce4eb802">Générer ▾</strong><span data-i18n="help.desc_991307d6"> — Génère du
|
||
contenu à partir de la sélection :</span><ul>
|
||
<li>
|
||
ℹ️ <strong>Explain this</strong> :
|
||
Explique le texte sélectionné de
|
||
façon claire
|
||
</li>
|
||
<li data-i18n="help.desc_e5cf90b2">
|
||
📝 <strong>Summarize</strong> :
|
||
Résume le texte de façon concise
|
||
</li>
|
||
<li data-i18n="help.desc_f2d4e369">
|
||
✏️
|
||
<strong>Continue writing</strong> :
|
||
Continue l'écriture à partir du
|
||
texte
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li data-i18n="help.desc_aec0ad2c">
|
||
<strong data-i18n="auto.62c3d50d">💬 Réécrire</strong><span data-i18n="help.desc_c63f02cc"> — Réécrit le
|
||
texte selon vos instructions personnalisées.
|
||
Une boîte de dialogue vous demande votre
|
||
instruction.</span></li>
|
||
<li data-i18n="help.desc_d9e8ab0b">
|
||
<strong data-i18n="auto.0257e77f">🧰 Boîte ▾</strong> — Outils de
|
||
conversion :
|
||
<ul>
|
||
<li>
|
||
📋
|
||
<strong>Convert to list</strong> :
|
||
Transforme le texte en liste
|
||
Markdown
|
||
</li>
|
||
<li data-i18n="help.desc_13d206d4">
|
||
📊
|
||
<strong>Convert to table</strong> :
|
||
Transforme en tableau Markdown
|
||
</li>
|
||
<li data-i18n="help.desc_50a33a05">
|
||
⚙️
|
||
<strong
|
||
>Generate frontmatter</strong
|
||
>
|
||
: Génère un bloc YAML frontmatter
|
||
</li>
|
||
<li data-i18n="help.desc_fa126609">
|
||
🔷
|
||
<strong>Convert to canvas</strong> :
|
||
Convertit en diagramme Mermaid.js
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.096367af">Indicateurs visuels</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_7ff2fa21">
|
||
Pendant une requête AI, un toast
|
||
<strong
|
||
>⏳ AI: traitement en cours...</strong
|
||
>
|
||
s'affiche
|
||
</li>
|
||
<li data-i18n="help.desc_a13f7f2c">
|
||
Une fois terminé,
|
||
<strong data-i18n="auto.4d281c6c">AI: texte traité ✓</strong> confirme
|
||
le succès
|
||
</li>
|
||
<li data-i18n="help.desc_32e3d66d">
|
||
En cas d'erreur de clé API :
|
||
<strong data-i18n="auto.13eb7a51">AI: clé API invalide</strong>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.2dad2bfd">Sauvegarde automatique</h3>
|
||
<p data-i18n="help.desc_19cfa369">
|
||
L'éditeur sauvegarde automatiquement après 2
|
||
secondes d'inactivité. Le bouton de sauvegarde
|
||
<strong data-i18n="help.ai_flash_green">flashe en vert</strong> brièvement pour
|
||
confirmer.
|
||
</p>
|
||
|
||
<h3 data-i18n="auto.272dd29a">Providers supportés</h3>
|
||
<table>
|
||
<tr>
|
||
<th>Provider</th>
|
||
<th>Variable .env</th>
|
||
<thdata-i18n="auto.033a9ddf">Modèle par défaut</th>
|
||
</tr>
|
||
<tr>
|
||
<td>DeepSeek</td>
|
||
<td><code>DEEPSEEK_API_KEY</code></td>
|
||
<td><code>deepseek-chat</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>OpenRouter</td>
|
||
<td><code>OPENROUTER_API_KEY</code></td>
|
||
<td><code>openai/gpt-4o-mini</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td>Gemini</td>
|
||
<td><code>GEMINI_API_KEY</code></td>
|
||
<td><code>gemini-2.0-flash</code></td>
|
||
</tr>
|
||
</table>
|
||
<p data-i18n="help.desc_555e0305">
|
||
Pour changer de provider par défaut :
|
||
<code>AI_DEFAULT_PROVIDER=openrouter</code>
|
||
</p>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-palette">
|
||
<h2 data-i18n="help.62308f96">⌨️ Palette de commandes</h2>
|
||
<p data-i18n="auto.774dbd63">
|
||
La palette de commandes permet d'accéder
|
||
rapidement aux fichiers et aux actions sans
|
||
utiliser la souris.
|
||
</p>
|
||
|
||
<h3 data-i18n="help.b6619ac9">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 data-i18n="help.6d547397">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 data-i18n="help.3cf370b1">Mode commandes</h3>
|
||
<p>
|
||
Tapez <code>></code> (ou Ctrl+Alt+Espace)
|
||
pour voir la liste des actions disponibles :
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
🏠 <strong data-i18n="viewer.breadcrumb_home">Accueil</strong> : Retour à
|
||
l'accueil
|
||
</li>
|
||
<li>
|
||
✏️ <strong data-i18n="auto.b893650a">É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 data-i18n="auto.aedff644">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 data-i18n="auto.195a8e44">Créer répertoire</strong> : Crée
|
||
un nouveau dossier
|
||
</li>
|
||
<li>
|
||
🗑️ <strong data-i18n="auto.5a486420">Supprimer répertoire</strong> :
|
||
Supprime un dossier et son contenu
|
||
</li>
|
||
<li>
|
||
🌓 <strong data-i18n="theme.change">Changer le thème</strong> :
|
||
Bascule clair/sombre
|
||
</li>
|
||
<li>
|
||
🔄 <strong data-i18n="config.reindex">Réindexer</strong> : Force la
|
||
réindexation complète
|
||
</li>
|
||
<li>
|
||
❓ <strong data-i18n="header.help">Aide</strong> : Ouvre ce guide
|
||
</li>
|
||
<li>
|
||
⚙️ <strong data-i18n="config.title">Configuration</strong> : Ouvre
|
||
les paramètres
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.nav_navigation">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 data-i18n="help.2a2e5b0f">⌨️ Raccourcis clavier</h2>
|
||
|
||
<h3 data-i18n="help.nav_navigation">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 data-i18n="auto.13c3ee2c">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 data-i18n="help.nav_interface">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 data-i18n="help.nav_tabs">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 data-i18n="auto.a131dfab">É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>
|
||
|
||
|
||
|
||
<!-- 🔗 Partage -->
|
||
<section class="help-section" id="help-partage">
|
||
<h2 data-i18n="help.8c65b2f2">🔗 Partage et Webhooks</h2>
|
||
|
||
<h3 data-i18n="help.public_shares">Publication publique</h3>
|
||
<p data-i18n="help.desc_13d90039">
|
||
ObsiGate permet de partager des documents via un
|
||
lien public temporaire.
|
||
</p>
|
||
<ul>
|
||
<li data-i18n="help.desc_7e86626c">
|
||
<strong data-i18n="help.share_button">Bouton Partager</strong><span data-i18n="help.desc_d66e911c"> : Dans les
|
||
actions du fichier, génère un lien unique</span></li>
|
||
<li data-i18n="help.desc_985d759b">
|
||
<strong>Token unique</strong><span data-i18n="help.desc_04493800"> : 64
|
||
caractères hexadécimaux, impossible à
|
||
deviner</span></li>
|
||
<li data-i18n="help.desc_ec5f7a26">
|
||
<strong>Expiration configurable</strong><span data-i18n="help.desc_858681a1"> :
|
||
Durée de vie en heures</span></li>
|
||
<li data-i18n="help.desc_071da87a">
|
||
<strong>Lecture seule</strong><span data-i18n="help.desc_e47d2328"> : La vue
|
||
publique n'affiche que le contenu sans
|
||
édition</span></li>
|
||
<li data-i18n="help.desc_2c220763">
|
||
<strong>Gestion des liens</strong><span data-i18n="help.desc_5e9a7fd9"> : Liste
|
||
et révocation dans les Configurations</span></li>
|
||
<li data-i18n="help.desc_cfe362a7">
|
||
<strong data-i18n="help.pdf_export">Export PDF</strong><span data-i18n="help.desc_e93517a5"> : Téléchargement
|
||
du document partagé en PDF via</span><code>/s/{token}/pdf</code>
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- 🪝 Webhooks -->
|
||
<section class="help-section" id="help-webhooks">
|
||
<h2 data-i18n="help.29afa01d">🪝 Webhooks</h2>
|
||
<p data-i18n="help.desc_a9c2c520">
|
||
Les webhooks permettent à ObsiGate de
|
||
<strong
|
||
data-i18n="help.webhook_notify">notifier automatiquement des services
|
||
externes</strong
|
||
>
|
||
lorsque des fichiers ou dossiers sont modifiés.
|
||
Chaque événement déclenche un
|
||
<code>POST</code> <span data-i18n="help.webhook_post">HTTP vers l'URL de votre</span>
|
||
choix, avec un payload JSON détaillé.
|
||
</p>
|
||
|
||
<h3 data-i18n="help.use_cases">Cas d'usage</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_2349271d">
|
||
<strong data-i18n="help.ci_cd">Automatisation CI/CD</strong><span data-i18n="help.desc_1ba39cc4"> :
|
||
Déclencher un build quand une note de
|
||
procédure est mise à jour</span></li>
|
||
<li data-i18n="help.desc_d915c72b">
|
||
<strong data-i18n="header.sync_status">Synchronisation</strong><span data-i18n="help.desc_d9cdaa89"> : Copier
|
||
les nouveaux fichiers vers un autre système
|
||
(SharePoint, Google Drive)</span></li>
|
||
<li data-i18n="help.desc_cc8e35ba">
|
||
<strong>Notifications</strong><span data-i18n="help.desc_6f7c5889"> : Alerter un
|
||
canal Slack/Discord quand un document est
|
||
créé</span></li>
|
||
<li data-i18n="help.desc_660051b0">
|
||
<strong data-i18n="help.external_audit">Audit externe</strong><span data-i18n="help.desc_599f3242"> : Logger
|
||
toutes les modifications dans une base de
|
||
données externe</span></li>
|
||
<li data-i18n="help.desc_89a8f5de">
|
||
<strong data-i18n="auto.a232672b">Déploiement</strong><span data-i18n="help.desc_2f2c16b5"> : Publier un
|
||
article de blog quand un fichier est marqué</span><code>publish: true</code>
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="auto.ba768f01">Événements supportés</h3>
|
||
<div style="overflow-x: auto">
|
||
<table
|
||
style="
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 0.85rem;
|
||
margin: 8px 0 16px;
|
||
"
|
||
>
|
||
<tr style="background: var(--bg-secondary)">
|
||
<th
|
||
style="
|
||
padding: 8px 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
data-i18n="auto.f5a8c116">
|
||
Événement
|
||
</th>
|
||
<th
|
||
style="
|
||
padding: 8px 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
data-i18n="auto.d4d28717">
|
||
Déclencheur
|
||
</th>
|
||
<th
|
||
style="
|
||
padding: 8px 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
data-i18n="auto.460b8298">
|
||
Données
|
||
</th>
|
||
</tr>
|
||
<tr>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>file_created</code>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
data-i18n="auto.a05514cb">
|
||
Création via l'API ou la palette
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>vault</code>,
|
||
<code>path</code>
|
||
</td>
|
||
</tr>
|
||
<tr style="background: var(--bg-secondary)">
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>file_deleted</code>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
data-i18n="auto.fc694490">
|
||
Suppression via l'API ou l'éditeur
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>vault</code>,
|
||
<code>path</code>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>file_renamed</code>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<span data-i18n="webhook.trigger_rename">Renommage via l'API</span>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>vault</code>,
|
||
<code>old_path</code>,
|
||
<code>new_path</code>
|
||
</td>
|
||
</tr>
|
||
<tr style="background: var(--bg-secondary)">
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>directory_created</code>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
data-i18n="auto.2bc66bab">
|
||
Création de dossier via l'API
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>vault</code>,
|
||
<code>path</code>
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>directory_deleted</code>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<span data-i18n="webhook.trigger_dir_delete">Suppression de dossier via l'API</span>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>vault</code>,
|
||
<code>path</code>
|
||
</td>
|
||
</tr>
|
||
<tr style="background: var(--bg-secondary)">
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>directory_renamed</code>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<span data-i18n="webhook.trigger_dir_rename">Renommage de dossier via l'API</span>
|
||
</td>
|
||
<td
|
||
style="
|
||
padding: 8px 12px;
|
||
border-bottom: 1px solid
|
||
var(--border);
|
||
"
|
||
>
|
||
<code>vault</code>,
|
||
<code>old_path</code>,
|
||
<code>new_path</code>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
</div>
|
||
<p data-i18n="help.desc_39e97b2f">
|
||
<em
|
||
data-i18n="help.webhook_note">Note : l'événement
|
||
<code>file_modified</code> est réservé pour
|
||
usage futur. Les modifications de contenu
|
||
via l'éditeur ne déclenchent pas encore de
|
||
webhook.</em
|
||
>
|
||
</p>
|
||
|
||
<h3 data-i18n="help.77f4f06e">Format du payload</h3>
|
||
<p data-i18n="help.desc_56760d7f">
|
||
Chaque webhook reçoit un <code>POST</code> avec
|
||
<code>Content-Type: application/json</code> :
|
||
</p>
|
||
<pre
|
||
style="
|
||
background: var(--bg-secondary);
|
||
padding: 12px;
|
||
border-radius: 8px;
|
||
overflow-x: auto;
|
||
font-size: 0.78rem;
|
||
"
|
||
data-i18n="help.desc_c1f72521"><code>{
|
||
"event": "file_created",
|
||
"timestamp": "2026-06-03T14:30:00.123456+00:00",
|
||
"data": {
|
||
"vault": "IT",
|
||
"path": "procedures/deploiement.md"
|
||
}
|
||
}</code></pre>
|
||
|
||
<h3 data-i18n="auto.28bf6aab">Sécurité : signature HMAC-SHA256</h3>
|
||
<p>
|
||
Si vous configurez un secret, chaque requête
|
||
inclut un header
|
||
<code>X-ObsiGate-Signature</code> :
|
||
</p>
|
||
<pre
|
||
style="
|
||
background: var(--bg-secondary);
|
||
padding: 12px;
|
||
border-radius: 8px;
|
||
overflow-x: auto;
|
||
font-size: 0.78rem;
|
||
"
|
||
data-i18n="help.desc_3db2812f"><code>X-ObsiGate-Signature: sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08</code></pre>
|
||
<p>
|
||
Pour vérifier côté récepteur : calculez
|
||
<code>HMAC-SHA256(corps_brut, secret)</code> et
|
||
comparez. Le header
|
||
<code>X-ObsiGate-Event</code> contient aussi le
|
||
type d'événement pour un routage rapide.
|
||
</p>
|
||
|
||
<h3 data-i18n="config.title">Configuration</h3>
|
||
<p data-i18n="help.desc_b6169f2e">
|
||
Les webhooks se gèrent dans le modal
|
||
<strong data-i18n="header.menu_config">Configurations</strong> (⚙️ menu
|
||
Options), section Webhooks. Réservé aux
|
||
administrateurs.
|
||
</p>
|
||
<ol>
|
||
<li data-i18n="help.desc_a601f22e">
|
||
Allez dans ⚙️ Configurations → onglet
|
||
Webhooks
|
||
</li>
|
||
<li data-i18n="help.desc_c992f2e5">
|
||
Remplissez :
|
||
<strong data-i18n="config.webhook_name_placeholder">Nom</strong> (descriptif),
|
||
<strong data-i18n="config.webhook_url_placeholder">URL</strong> (endpoint cible),
|
||
<strong>Secret</strong> (optionnel)
|
||
</li>
|
||
<li data-i18n="auto.7c9cdc3c">Cochez les événements à écouter</li>
|
||
<li data-i18n="help.desc_f58da6e1">Cliquez <strong data-i18n="config.add_webhook">Ajouter</strong></li>
|
||
</ol>
|
||
<p data-i18n="help.desc_3da1896a">
|
||
Les webhooks peuvent être activés/désactivés,
|
||
modifiés ou supprimés à tout moment. Le
|
||
<code>last_fired_at</code> indique la dernière
|
||
exécution.
|
||
</p>
|
||
|
||
<h3 data-i18n="help.550b0240">Exemples concrets</h3>
|
||
|
||
<h4 data-i18n="auto.b419c2c2">Récepteur Python (Flask)</h4>
|
||
<pre
|
||
style="
|
||
background: var(--bg-secondary);
|
||
padding: 12px;
|
||
border-radius: 8px;
|
||
overflow-x: auto;
|
||
font-size: 0.78rem;
|
||
"
|
||
data-i18n="help.desc_6d68fbc9"><code>from flask import Flask, request\nimport hmac, hashlib\n\napp = Flask(__name__)\nWEBHOOK_SECRET = "mon-secret" # même que dans ObsiGate\n\[email protected]("/webhook", methods=["POST"])\ndef webhook():\n # Vérifier la signature\n signature = request.headers.get("X-ObsiGate-Signature", "")\n body = request.get_data()\n expected = "sha256=" + hmac.new(\n WEBHOOK_SECRET.encode(), body, hashlib.sha256\n ).hexdigest()\n if not hmac.compare_digest(signature, expected):\n return "Invalid signature", 403\n\n payload = request.get_json()\n print(f"Événement: {payload['event']}")\n print(f"Fichier: {payload['data']['vault']}/{payload['data']['path']}")\n return "OK", 200\n\napp.run(port=5000)</code></pre>
|
||
|
||
<h4 data-i18n="help.d1ea1dc6">n8n / Make (no-code)</h4>
|
||
<ol>
|
||
<li data-i18n="help.desc_6bc48f59">
|
||
Créez un
|
||
<strong>Webhook Trigger</strong> dans n8n ou
|
||
Make
|
||
</li>
|
||
<li data-i18n="help.desc_7819b56f">
|
||
Copiez l'URL générée (ex:
|
||
<code
|
||
>https://n8n.monserveur.com/webhook/abc123</code
|
||
>)
|
||
</li>
|
||
<li data-i18n="help.desc_7b45490b">
|
||
Dans ObsiGate, ajoutez un webhook pointant
|
||
vers cette URL
|
||
</li>
|
||
<li data-i18n="auto.14c75ac6">Sélectionnez les événements souhaités</li>
|
||
<li data-i18n="auto.2a5af19b">
|
||
Le workflow se déclenche automatiquement à
|
||
chaque événement
|
||
</li>
|
||
</ol>
|
||
|
||
<h4 data-i18n="help.229fd3e2">Notification Discord</h4>
|
||
<p>
|
||
Utilisez un webhook relais (n8n, Make, ou un
|
||
script) pour transformer le payload ObsiGate en
|
||
message Discord :
|
||
</p>
|
||
<pre
|
||
style="
|
||
background: var(--bg-secondary);
|
||
padding: 12px;
|
||
border-radius: 8px;
|
||
overflow-x: auto;
|
||
font-size: 0.78rem;
|
||
"
|
||
data-i18n="help.desc_fc9391f3"><code># Exemple avec curl + jq dans un script bash
|
||
WEBHOOK_URL="https://discord.com/api/webhooks/..."
|
||
OBSIGATE_SECRET="mon-secret"
|
||
|
||
# Lire le payload depuis stdin
|
||
read -r payload
|
||
event=$(echo "$payload" | jq -r '.event')
|
||
path=$(echo "$payload" | jq -r '.data.path')
|
||
|
||
curl -H "Content-Type: application/json" -d "{
|
||
\"content\": \"📝 **$event** — $path\"
|
||
}" "$WEBHOOK_URL"</code></pre>
|
||
|
||
<h4 data-i18n="help.40dd7e38">Tester avec curl</h4>
|
||
<pre
|
||
style="
|
||
background: var(--bg-secondary);
|
||
padding: 12px;
|
||
border-radius: 8px;
|
||
overflow-x: auto;
|
||
font-size: 0.78rem;
|
||
"
|
||
><code># Simuler ce qu'ObsiGate envoie (pour tester votre endpoint)
|
||
curl -X POST https://votre-serveur.com/webhook \
|
||
-H "Content-Type: application/json" \
|
||
-H "X-ObsiGate-Event: file_created" \
|
||
-H "X-ObsiGate-Signature: sha256=$(echo -n '{"event":"file_created",...}' | openssl dgst -sha256 -hmac 'mon-secret' | cut -d' ' -f2)" \
|
||
-d '{"event":"file_created","timestamp":"2026-06-03T14:30:00Z","data":{"vault":"IT","path":"notes/test.md"}}'</code></pre>
|
||
|
||
<h3 data-i18n="help.381abec7">Limitations actuelles</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_85effb89">
|
||
Timeout de <strong>5 secondes</strong> par
|
||
requête — les webhooks sont "fire and
|
||
forget" (pas de retry)
|
||
</li>
|
||
<li data-i18n="help.desc_dc4d7186">
|
||
Les modifications détectées par le watcher
|
||
filesystem (watchdog)
|
||
<strong data-i18n="auto.98c547ea">ne déclenchent pas</strong> de
|
||
webhooks — seules les opérations via l'API
|
||
REST sont prises en compte
|
||
</li>
|
||
<li data-i18n="help.desc_d3a71d97">
|
||
<code>file_modified</code> n'est pas encore
|
||
dispatché (réservé pour version future)
|
||
</li>
|
||
<li data-i18n="auto.1d3330cc">Pas de retry automatique en cas d'échec</li>
|
||
<li data-i18n="auto.4dfa6a25">
|
||
Pas de filtrage par vault — un webhook
|
||
écoute toutes les vaults
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
<section class="help-section" id="help-sauvegardes">
|
||
<h2 data-i18n="help.62549eca">💾 Sauvegardes et Audits</h2>
|
||
|
||
<h3 data-i18n="help.backup_auto">Backup automatique</h3>
|
||
<p data-i18n="auto.ab5e6155">
|
||
ObsiGate crée automatiquement des sauvegardes
|
||
avant chaque modification destructive.
|
||
</p>
|
||
<ul>
|
||
<li data-i18n="help.desc_7671e56a">
|
||
<strong data-i18n="help.before_write">Avant écriture</strong> : Sauvegarde
|
||
du contenu original dans
|
||
<code>.obsigate-backup/</code>
|
||
</li>
|
||
<li data-i18n="help.desc_e7e3157a">
|
||
<strong>Timestamp</strong><span data-i18n="help.desc_31e7253b"> : Chaque backup
|
||
est horodaté</span></li>
|
||
<li data-i18n="help.desc_a69804cd">
|
||
<strong data-i18n="auto.41d7c6af">Répertoire dédié</strong> :
|
||
<code>.obsigate-backup/</code> dans le
|
||
répertoire de la vault
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.audit_log">Audit log</h3>
|
||
<p data-i18n="auto.2bc24d2e">
|
||
Toutes les opérations sensibles sont tracées
|
||
dans un journal.
|
||
</p>
|
||
<ul>
|
||
<li data-i18n="help.desc_a974f7a6">
|
||
<strong>Journal</strong> : Fichier
|
||
<code>data/audit.log</code> au format JSON
|
||
lines
|
||
</li>
|
||
<li data-i18n="help.desc_3c4711b8">
|
||
<strong data-i18n="auto.598a0ca7">Événements tracés</strong><span data-i18n="help.desc_9f321d1e"> :
|
||
Écritures, suppressions, changements de
|
||
configuration</span></li>
|
||
<li data-i18n="help.desc_68c2b170">
|
||
<strong>Rotation</strong><span data-i18n="help.desc_19cf5730"> : Rotation
|
||
automatique à 10 Mo</span></li>
|
||
</ul>
|
||
</section>
|
||
|
||
<!-- 🛡️ Sécurité -->
|
||
<section class="help-section" id="help-securite">
|
||
<h2 data-i18n="auto.37561472">🛡️ Sécurité</h2>
|
||
|
||
<h3 data-i18n="help.c48fb18a">Authentification</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_7708f226">
|
||
<strong>JWT + Argon2id</strong><span data-i18n="help.desc_8f0bffe3"> : Tokens JWT
|
||
avec mots de passe hachés Argon2id</span></li>
|
||
<li data-i18n="help.desc_b54c21ef">
|
||
<strong data-i18n="auto.72e515fa">Contrôle d'accès par vault</strong>
|
||
: Chaque utilisateur voit uniquement ses
|
||
vaults
|
||
</li>
|
||
<li data-i18n="help.desc_f952db17">
|
||
<strong>Refresh tokens</strong> : Cookies
|
||
HttpOnly avec rotation automatique
|
||
</li>
|
||
<li data-i18n="help.desc_1577912b">
|
||
<strong data-i18n="help.rate_limiting">Rate limiting</strong> : 10
|
||
tentatives / 15 min par IP + verrouillage
|
||
compte
|
||
</li>
|
||
<li data-i18n="help.desc_d646b709">
|
||
<strong>Compte admin</strong><span data-i18n="help.desc_5fc28b7d"> : Créé
|
||
automatiquement au premier démarrage</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.83f1d9ca">Protection</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_bc08f215">
|
||
<strong>Secret redactor</strong><span data-i18n="help.desc_9846fc07"> : Masque
|
||
JWT, clés API, tokens GitHub dans les
|
||
aperçus</span></li>
|
||
<li data-i18n="help.desc_7f1d0512">
|
||
<strong>Path traversal</strong> : Validation
|
||
des chemins contre les attaques
|
||
<code>../</code>
|
||
</li>
|
||
<li data-i18n="help.desc_9d0e39d0">
|
||
<strong>Headers CSP</strong> :
|
||
Content-Security-Policy, X-Frame-Options,
|
||
XSS-Protection
|
||
</li>
|
||
<li data-i18n="help.desc_1f11691c">
|
||
<strong data-i18n="help.atomic_writes">Atomic writes</strong><span data-i18n="help.desc_752789ab"> : Écriture
|
||
via fichier temporaire + renommage atomique</span></li>
|
||
<li data-i18n="help.desc_723ed8db">
|
||
<strong>Non-root Docker</strong> : Conteneur
|
||
tourne avec UID 1000
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section
|
||
class="help-section"
|
||
id="help-personnalisation"
|
||
>
|
||
<h2 data-i18n="help.86e3825d">🎨 Personnalisation</h2>
|
||
|
||
<h3 data-i18n="auto.337d8626">Thème clair/sombre</h3>
|
||
<p data-i18n="help.theme_toggle">Basculez entre les thèmes :</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="help.menu_options">Menu Options</strong><span data-i18n="help.desc_beed5686"> : Cliquez sur
|
||
"Thème" dans le menu</span></li>
|
||
<li>
|
||
<strong>Raccourci</strong> :
|
||
<code>Ctrl+T</code>
|
||
</li>
|
||
<li>
|
||
<strong>Persistance</strong><span data-i18n="help.desc_e5b67e3d"> : Votre choix
|
||
est sauvegardé en localStorage</span></li>
|
||
<li>
|
||
<strong>Highlight.js</strong><span data-i18n="help.desc_d5c977ac"> : Les blocs de
|
||
code s'adaptent au thème</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.7bcbb2e3">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 data-i18n="auto.1a8a8118">Glisser-déposer</strong> : Cliquez
|
||
et glissez pour ajuster
|
||
</li>
|
||
<li>
|
||
<strong>Limites</strong> : Min 200px, Max
|
||
500px
|
||
</li>
|
||
<li>
|
||
<strong>Persistance</strong><span data-i18n="help.desc_6a80241e"> : La largeur
|
||
est sauvegardée</span></li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="auto.9122fd5c">Configuration avancée</h3>
|
||
<p>
|
||
Le modal Configurations (menu Options) permet de
|
||
:
|
||
</p>
|
||
<ul>
|
||
<li>
|
||
<strong data-i18n="config.section_search">Paramètres de recherche</strong><span data-i18n="help.desc_6b88a375"> :
|
||
Délai debounce, résultats par page, timeout</span></li>
|
||
<li>
|
||
<strong data-i18n="settings.backend_section">Paramètres backend</strong><span data-i18n="help.desc_5d0fbb81"> :
|
||
Workers, boosts TF-IDF, expansions préfixe</span></li>
|
||
<li>
|
||
<strong data-i18n="config.tag_filtering_label">Filtrage de tags</strong> : Patterns
|
||
pour masquer les tags template
|
||
</li>
|
||
<li>
|
||
<strong data-i18n="config.diagnostics">Diagnostics</strong><span data-i18n="help.desc_6ae5342c"> : Stats index,
|
||
mémoire, moteur de recherche</span></li>
|
||
<li>
|
||
<strong data-i18n="auto.83a0efdf">Réindexation</strong> : Forcer un
|
||
rescan des vaults
|
||
</li>
|
||
</ul>
|
||
</section>
|
||
|
||
<section class="help-section" id="help-astuces">
|
||
<h2 data-i18n="help.686f8313">💡 Astuces et bonnes pratiques</h2>
|
||
|
||
<h3 data-i18n="auto.559ef1da">Workflow recommandé</h3>
|
||
<ol>
|
||
<li data-i18n="help.desc_625112fd">
|
||
<strong data-i18n="auto.678711b5">Sélectionnez un contexte</strong><span data-i18n="help.desc_39979e71"> :
|
||
Choisissez un vault pour réduire le bruit</span></li>
|
||
<li data-i18n="help.desc_9186a3a3">
|
||
<strong>Explorez l'arborescence</strong> :
|
||
Naviguez dans les dossiers
|
||
</li>
|
||
<li data-i18n="help.desc_93902d18">
|
||
<strong data-i18n="help.tip_use_tags">Utilisez les tags</strong> : Filtrez
|
||
par tags pour affiner
|
||
</li>
|
||
<li data-i18n="help.desc_cdf7bb46">
|
||
<strong>Recherchez intelligemment</strong><span data-i18n="help.desc_ae213f54"> :
|
||
Combinez opérateurs et texte libre</span></li>
|
||
<li data-i18n="help.desc_5396ed9e">
|
||
<strong>Profitez de l'historique</strong><span data-i18n="help.desc_71eeb16a"> :
|
||
Réutilisez vos recherches fréquentes</span></li>
|
||
</ol>
|
||
|
||
<h3 data-i18n="help.fe388b67">Optimisations</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_1a04ae18">
|
||
<strong data-i18n="help.tip_hide_sidebar">Masquez la sidebar</strong> : Plus
|
||
d'espace pour le contenu
|
||
</li>
|
||
<li data-i18n="help.desc_0f9a1e5b">
|
||
<strong
|
||
data-i18n="help.tip_sidebar_filter">Utilisez le filtrage sidebar</strong
|
||
>
|
||
: Plus rapide que la recherche globale pour
|
||
trouver un fichier
|
||
</li>
|
||
<li data-i18n="help.desc_6902f20d">
|
||
<strong data-i18n="auto.3be698f6">Favorisez les opérateurs</strong> :
|
||
<code>tag:</code> et
|
||
<code>vault:</code> accélèrent la recherche
|
||
</li>
|
||
<li data-i18n="help.desc_664b1d09">
|
||
<strong data-i18n="help.breadcrumb_clickable">Breadcrumb cliquable</strong> :
|
||
Repositionnez rapidement la sidebar
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.2a92203f">Trucs et astuces</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_58d2326f">
|
||
<strong>Navigation visuelle</strong> : Le
|
||
breadcrumb repositionne automatiquement la
|
||
sidebar
|
||
</li>
|
||
<li data-i18n="help.desc_698d92ec">
|
||
<strong>Gestion de l'espace</strong><span data-i18n="help.desc_287be69c"> :
|
||
Réduisez les sections Vaults/Tags selon vos
|
||
besoins</span></li>
|
||
<li data-i18n="help.desc_e6129268">
|
||
<strong>Confort de lecture</strong> :
|
||
Ajustez la largeur de la sidebar
|
||
</li>
|
||
<li data-i18n="help.desc_5374685a">
|
||
<strong>Mobile-friendly</strong> : Utilisez
|
||
le bouton hamburger sur mobile
|
||
</li>
|
||
<li data-i18n="help.desc_443b76b5">
|
||
<strong data-i18n="help.wikilinks">Wikilinks</strong> : Naviguez entre
|
||
notes comme dans Obsidian
|
||
</li>
|
||
<li data-i18n="help.desc_0739c6a9">
|
||
<strong>Images</strong> : Support complet
|
||
des syntaxes Obsidian
|
||
</li>
|
||
</ul>
|
||
|
||
<h3 data-i18n="help.advanced_use_cases">Cas d'usage avancés</h3>
|
||
<ul>
|
||
<li data-i18n="help.desc_87b348c3">
|
||
<strong data-i18n="auto.b86ba5ea">Recherche multi-critères</strong> :
|
||
<code
|
||
>tag:docker tag:linux vault:IT
|
||
nginx</code
|
||
>
|
||
</li>
|
||
<li data-i18n="help.desc_40c92863">
|
||
<strong>Exploration par tags</strong> :
|
||
Cliquez sur un tag dans une note pour voir
|
||
toutes les notes similaires
|
||
</li>
|
||
<li data-i18n="help.desc_26f81732">
|
||
<strong data-i18n="auto.4fa5d7c2">Édition rapide</strong><span data-i18n="help.desc_cb6f0bfd"> : Ouvrez
|
||
l'éditeur, modifiez, sauvegardez</span></li>
|
||
<li data-i18n="help.desc_99c6f0ec">
|
||
<strong data-i18n="help.export">Export</strong><span data-i18n="help.desc_f9083ce5"> : Téléchargez des
|
||
fichiers pour backup ou partage</span></li>
|
||
<li data-i18n="help.desc_ecf302ae">
|
||
<strong data-i18n="auto.79f6e1dd">Multi-fenêtres</strong><span data-i18n="help.desc_9cb5974c"> : Ouvrez
|
||
plusieurs notes dans des onglets séparés</span></li>
|
||
</ul>
|
||
</section>
|
||
|
||
<div class="help-footer">
|
||
<p data-i18n="help.desc_eebf177f">
|
||
<strong>ObsiGate v1.7.0</strong> - Porte
|
||
d'entrée web pour vos vaults Obsidian
|
||
</p>
|
||
<p data-i18n="help.desc_188bc423">
|
||
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>
|
||
|
||
<!-- Find in Page Bar -->
|
||
<div class="find-in-page-bar" id="find-in-page-bar" hidden>
|
||
<div class="find-in-page-content">
|
||
<i data-lucide="search" class="find-icon"></i>
|
||
<input
|
||
type="text"
|
||
id="find-input"
|
||
data-i18n-placeholder="settings.search_placeholder" placeholder="Rechercher..."
|
||
autocomplete="off"
|
||
aria-label="Rechercher dans la page"
|
||
/>
|
||
<span class="find-counter" id="find-counter" aria-live="polite"
|
||
>0 occurrence</span
|
||
>
|
||
<div class="find-nav-buttons">
|
||
<button
|
||
class="find-btn"
|
||
id="find-prev"
|
||
title="Précédent (Shift+Enter)"
|
||
aria-label="Résultat précédent"
|
||
disabled
|
||
>
|
||
<i
|
||
data-lucide="chevron-up"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
<button
|
||
class="find-btn"
|
||
id="find-next"
|
||
title="Suivant (Enter)"
|
||
aria-label="Résultat suivant"
|
||
disabled
|
||
>
|
||
<i
|
||
data-lucide="chevron-down"
|
||
style="width: 14px; height: 14px"
|
||
></i>
|
||
</button>
|
||
</div>
|
||
<div class="find-options">
|
||
<button
|
||
class="find-btn find-option-btn"
|
||
id="find-case-sensitive"
|
||
title="Respecter la casse"
|
||
aria-label="Respecter la casse"
|
||
aria-pressed="false"
|
||
>
|
||
<span class="find-option-text">Aa</span>
|
||
</button>
|
||
<button
|
||
class="find-btn find-option-btn"
|
||
id="find-whole-word"
|
||
title="Mot entier"
|
||
aria-label="Mot entier"
|
||
aria-pressed="false"
|
||
>
|
||
<span class="find-option-text">abc</span>
|
||
</button>
|
||
<button
|
||
class="find-btn find-option-btn"
|
||
id="find-regex"
|
||
title="Expression régulière"
|
||
aria-label="Expression régulière"
|
||
aria-pressed="false"
|
||
>
|
||
<span class="find-option-text">.*</span>
|
||
</button>
|
||
</div>
|
||
<button
|
||
class="find-btn find-close"
|
||
id="find-close"
|
||
title="Fermer (Escape)"
|
||
aria-label="Fermer la recherche"
|
||
>
|
||
<i data-lucide="x" style="width: 16px; height: 16px"></i>
|
||
</button>
|
||
</div>
|
||
<div class="find-error" id="find-error" hidden></div>
|
||
</div>
|
||
|
||
<script type="module" src="/static/js/app.js"></script>
|
||
|
||
<!-- ── Mobile Bottom Toolbar ── -->
|
||
<nav
|
||
class="mobile-toolbar"
|
||
id="mobile-toolbar"
|
||
aria-label="Barre d'outils mobile"
|
||
>
|
||
<button
|
||
class="mt-btn"
|
||
id="mt-explorer"
|
||
title="Explorateur"
|
||
aria-label="Explorateur de vault"
|
||
>
|
||
<i
|
||
data-lucide="folder-open"
|
||
style="width: 20px; height: 20px"
|
||
></i>
|
||
<span class="mt-label">Explorer</span>
|
||
</button>
|
||
<button
|
||
class="mt-btn"
|
||
id="mt-search"
|
||
title="Rechercher un fichier"
|
||
aria-label="Rechercher un fichier"
|
||
>
|
||
<i data-lucide="search" style="width: 20px; height: 20px"></i>
|
||
<span class="mt-label" data-i18n="settings.search">Recherche</span>
|
||
</button>
|
||
<button
|
||
class="mt-btn mt-btn-primary"
|
||
id="mt-palette"
|
||
title="Commandes"
|
||
aria-label="Palette de commandes"
|
||
>
|
||
<i data-lucide="terminal" style="width: 20px; height: 20px"></i>
|
||
<span class="mt-label" data-i18n="palette.mode_commands">Commandes</span>
|
||
</button>
|
||
<button
|
||
class="mt-btn"
|
||
id="mt-tabs"
|
||
title="Onglets"
|
||
aria-label="Onglets ouverts"
|
||
>
|
||
<i data-lucide="files" style="width: 20px; height: 20px"></i>
|
||
<span class="mt-badge" id="mt-tab-count" style="display: none"
|
||
>0</span
|
||
>
|
||
<span class="mt-label" data-i18n="help.nav_tabs">Onglets</span>
|
||
</button>
|
||
</nav>
|
||
|
||
<!-- ── Mobile Tab Switcher (bottom sheet) ── -->
|
||
<div class="mt-tab-switcher" id="mt-tab-switcher">
|
||
<div class="mt-sheet-handle"></div>
|
||
<div class="mt-sheet-header">
|
||
<span class="mt-sheet-title">Fichiers ouverts</span>
|
||
<div class="mt-sheet-actions">
|
||
<button
|
||
class="mt-sheet-close-all"
|
||
id="mt-close-all"
|
||
title="Fermer tout"
|
||
aria-label="Fermer tous les fichiers"
|
||
>
|
||
Fermer tout
|
||
</button>
|
||
<button
|
||
class="mt-sheet-close"
|
||
id="mt-sheet-close"
|
||
aria-label="Fermer"
|
||
>
|
||
✕
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="mt-sheet-list" id="mt-tab-list"></div>
|
||
</div>
|
||
<div class="mt-overlay" id="mt-overlay"></div>
|
||
<!-- Floating results bar (outside content-area, survives innerHTML) -->
|
||
<div class="results-bar" id="results-bar" style="display:none">
|
||
<span class="results-bar-count" id="rb-count">0/0</span>
|
||
<button class="results-bar-btn" id="rb-prev" title="Resultat precedent" aria-label="Precedent">↑</button>
|
||
<button class="results-bar-btn" id="rb-next" title="Resultat suivant" aria-label="Suivant">↓</button>
|
||
<span class="results-bar-sep"></span>
|
||
<button class="results-bar-btn tog" id="rb-case" title="Respecter la casse (Alt-C)">Aa</button>
|
||
<button class="results-bar-btn tog" id="rb-word" title="Mot entier (Alt-W)">wd</button>
|
||
<button class="results-bar-btn tog" id="rb-regex" title="Expression reguliere (Alt-R)">.*</button>
|
||
</div>
|
||
<!-- Offline conflict resolution modal -->
|
||
<div class="editor-modal" id="offline-conflict-modal">
|
||
<div class="editor-container" style="max-width:520px">
|
||
<div class="editor-header">
|
||
<span class="editor-brand">Conflit hors-ligne</span>
|
||
<div class="editor-spacer"></div>
|
||
<button class="editor-btn" id="offline-conflict-close" title="Fermer" aria-label="Fermer">✕</button>
|
||
</div>
|
||
<div class="editor-body" style="padding:20px;overflow:auto">
|
||
<p style="color:var(--text-secondary);margin-bottom:12px" id="offline-conflict-msg"></p>
|
||
<div style="display:flex;gap:8px">
|
||
<button class="editor-btn primary" id="offline-conflict-keep-local">Garder ma version</button>
|
||
<button class="editor-btn" id="offline-conflict-keep-server" data-i18n="offline.keep_server">Garder version serveur</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- About Modal -->
|
||
<div class="about-overlay" id="about-overlay">
|
||
<div class="about-modal">
|
||
<button class="about-close" id="about-close" aria-label="Fermer">×</button>
|
||
<div class="about-hero">
|
||
<div class="about-logo">
|
||
<svg width="56" height="56" viewBox="0 0 56 56" fill="none">
|
||
<rect width="56" height="56" rx="14" fill="var(--accent)" opacity="0.15"/>
|
||
<rect x="12" y="8" width="14" height="18" rx="3" fill="var(--accent)" opacity="0.9"/>
|
||
<rect x="29" y="8" width="14" height="18" rx="3" fill="var(--accent)" opacity="0.5"/>
|
||
<rect x="12" y="30" width="14" height="18" rx="3" fill="var(--accent)" opacity="0.7"/>
|
||
<rect x="29" y="30" width="14" height="18" rx="3" fill="var(--accent)" opacity="0.35"/>
|
||
</svg>
|
||
</div>
|
||
<h1 class="about-title" data-i18n="header.logo">ObsiGate</h1>
|
||
<p class="about-tagline">Vos notes Obsidian,<br>simplement accessibles.</p>
|
||
<span class="about-version">v2.0.0-dev</span>
|
||
</div>
|
||
<div class="about-body">
|
||
<div class="about-stats">
|
||
<div class="about-stat">
|
||
<span class="about-stat-value" id="about-stat-files">—</span>
|
||
<span class="about-stat-label" data-i18n="palette.mode_files">Fichiers</span>
|
||
</div>
|
||
<div class="about-stat">
|
||
<span class="about-stat-value" id="about-stat-vaults">—</span>
|
||
<span class="about-stat-label" data-i18n="sidebar.tab_vaults">Vaults</span>
|
||
</div>
|
||
<div class="about-stat">
|
||
<span class="about-stat-value">285</span>
|
||
<span class="about-stat-label">Tests</span>
|
||
</div>
|
||
</div>
|
||
<div class="about-stack">
|
||
<h3>Construit avec</h3>
|
||
<div class="about-stack-grid">
|
||
<span class="about-stack-badge">🐍 FastAPI</span>
|
||
<span class="about-stack-badge">⚡ vanilla JS</span>
|
||
<span class="about-stack-badge">🎨 CSS custom</span>
|
||
<span class="about-stack-badge">🐳 Docker</span>
|
||
<span class="about-stack-badge">🔍 TF-IDF</span>
|
||
<span class="about-stack-badge">📝 CodeMirror 6</span>
|
||
<span class="about-stack-badge">🧜 Mermaid.js</span>
|
||
<span class="about-stack-badge">🧠 Argon2id</span>
|
||
<span class="about-stack-badge">🔄 Watchdog</span>
|
||
<span class="about-stack-badge">📊 WeasyPrint</span>
|
||
<span class="about-stack-badge">🧪 Playwright</span>
|
||
<span class="about-stack-badge">🤖 AI multi-provider</span>
|
||
</div>
|
||
</div>
|
||
<div class="about-footer">
|
||
<div class="about-meta">
|
||
<span>Derniere livraison : <strong id="about-build-date">Juin 2026</strong></span>
|
||
<span>Git : <strong id="about-commit">—</strong></span>
|
||
</div>
|
||
<p class="about-joke" id="about-joke"></p>
|
||
<p class="about-copy">© 2026 — Fait avec ☕, 🎧 et quelques <code>git push --force</code> accidentels.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</body>
|
||
</html>
|