fix(ui,help): #61 unified dynamic version display + full guide sections for AI editor & plugins
CI / lint (push) Successful in 54s
CI / security (push) Successful in 35s
CI / test (push) Successful in 1m13s
CI / build (push) Successful in 32s
CI / e2e (push) Failing after 22m0s
Desktop Build / build-windows (push) Canceled after 0s
Desktop Build / build-linux (push) Canceled after 0s

This commit is contained in:
2026-09-10 09:44:41 -04:00
parent e81dd9a7ec
commit ffa07b7df4
5 changed files with 180 additions and 51 deletions
+73 -4
View File
@@ -1455,8 +1455,6 @@
<li><a href="#cfg-webhooks" class="help-nav-link" data-i18n="config.section_webhooks"></a></li>
<li><a href="#cfg-partages-publics" class="help-nav-link" data-i18n="config.section_shares"></a></li>
</ul>
<li>
<a href="#help-plugins" class="help-nav-link"
</nav>
<div class="help-content" id="config-scroll">
<div class="config-content">
@@ -2817,7 +2815,7 @@
>
</li>
<li>
<a href="#help-ia" class="help-nav-link"
<a href="#help-ai" class="help-nav-link"
data-i18n="help.nav_ai">🤖 IA Éditeur</a
>
</li>
@@ -2865,6 +2863,11 @@
data-i18n="help.nav_tips">💡 Astuces</a
>
</li>
<li>
<a href="#help-plugins" class="help-nav-link"
data-i18n="help.nav_plugins">🧩 Plugins</a
>
</li>
</ul>
</nav>
<div class="help-content">
@@ -4759,9 +4762,74 @@ curl -X POST https://votre-serveur.com/webhook \
</ul>
</section>
<!-- 🧩 Plugins -->
<section class="help-section" id="help-plugins">
<h2 data-i18n="help.plugins_title">🧩 Plugins</h2>
<p data-i18n="help.plugins_intro">
Les plugins étendent ObsiGate : affichage personnalisé des
fichiers, filtres de recherche, actions d'édition, widgets
et intégrations. Ils s'exécutent dans des Web Workers
sandboxés — isolés de la page pour la sécurité.
</p>
<h3 data-i18n="help.plugins_install">Installation</h3>
<ol>
<li data-i18n="help.plugins_install_1">Ouvrez Réglages → 🧩 Plugins.</li>
<li data-i18n="help.plugins_install_2">Cliquez « Installer un plugin ».</li>
<li data-i18n="help.plugins_install_3">Sélectionnez un fichier <code>.zip</code> contenant le manifest
<code>plugin.json</code> + le code du plugin.</li>
<li data-i18n="help.plugins_install_4">Le manifest est validé (nom, version semver, hooks, permissions)
avant installation.</li>
</ol>
<h3 data-i18n="help.plugins_manage">Gestion</h3>
<ul>
<li data-i18n="help.plugins_manage_1"><strong>Activer / Désactiver</strong> : boutons sur chaque plugin — les
hooks ne tournent que si le plugin est activé.</li>
<li data-i18n="help.plugins_manage_2"><strong>Désinstaller</strong> : supprime définitivement le plugin du vault.</li>
<li data-i18n="help.plugins_manage_3"><strong>Code</strong> : visualisez le code source du plugin installé.</li>
</ul>
<h3 data-i18n="help.plugins_dev">Développer un plugin</h3>
<p data-i18n="help.plugins_dev_intro">
Téléchargez le modèle depuis Réglages → Plugins → « Obtenir le
modèle ». Un plugin se compose d'un manifest
<code>plugin.json</code> et d'un fichier principal (ex.
<code>index.js</code>).
</p>
<h3 data-i18n="help.plugins_hooks">Hooks disponibles</h3>
<ul>
<li><strong data-i18n="help.plugins_hook_render">onFileRender</strong> :
<span data-i18n="help.plugins_hook_render_desc">transforme le contenu affiché d'un fichier.</span></li>
<li><strong data-i18n="help.plugins_hook_search">onSearchFilter</strong> :
<span data-i18n="help.plugins_hook_search_desc">filtre les résultats de recherche.</span></li>
<li><strong data-i18n="help.plugins_hook_editor">onEditorAction</strong> :
<span data-i18n="help.plugins_hook_editor_desc">intercepte les actions de l'éditeur.</span></li>
<li><strong data-i18n="help.plugins_hook_sidebar">onSidebarItem</strong> :
<span data-i18n="help.plugins_hook_sidebar_desc">ajoute des éléments à la barre latérale.</span></li>
<li><strong data-i18n="help.plugins_hook_file">onFileCreate / onFileDelete</strong> :
<span data-i18n="help.plugins_hook_file_desc">réagit à la création / suppression de fichiers.</span></li>
<li><strong data-i18n="help.plugins_hook_vault">onVaultMount</strong> :
<span data-i18n="help.plugins_hook_vault_desc">exécuté au chargement d'un vault.</span></li>
</ul>
<h3 data-i18n="help.plugins_security">Sécurité</h3>
<ul>
<li data-i18n="help.plugins_security_1"><strong>Sandbox Web Worker</strong> : le code plugin tourne isolé, sans
accès direct au DOM.</li>
<li data-i18n="help.plugins_security_2"><strong>Permissions</strong> : chaque hook déclaré doit être satisfait
par les permissions du manifest.</li>
<li data-i18n="help.plugins_security_3"><strong>Empaquetage sécurisé</strong> : le .zip est vérifié contre le
path traversal à l'installation.</li>
<li data-i18n="help.plugins_security_4"><strong>Admin uniquement</strong> : l'installation et la suppression
requièrent le rôle admin.</li>
</ul>
</section>
<div class="help-footer">
<p>
<strong>ObsiGate v1.7.0</strong> - Porte
<strong data-i18n="help.footer_version">ObsiGate <span id="help-version"></span></strong> - Porte
d'entrée web pour vos vaults Obsidian
</p>
<p>
@@ -4773,6 +4841,7 @@ curl -X POST https://votre-serveur.com/webhook \
>.
</p>
</div>
</div>
</div>
</div>
+8 -11
View File
@@ -23,6 +23,7 @@ import PaneManager from './pane-manager.js';
import { initDesktopIntegration, isTauriEnv } from './desktop.js';
import { initPush } from './push.js';
import { initPlugins } from './plugins.js';
import { populateVersions } from './config.js';
// =========================================================================
// Initialization — mirrors the original app.js init() ordering
@@ -123,15 +124,11 @@ document.addEventListener("DOMContentLoaded", () => {
if (typeof window.__obsigateBootReady === "function") window.__obsigateBootReady();
}
// Show version in header — always visible, fallback before the async fetch
const versionBadge = document.getElementById('version-badge');
if (versionBadge) {
versionBadge.textContent = window.__OBSIGATE_VERSION || '…';
}
fetch('/api/health')
.then(r => r.json())
.then(d => {
const badge = document.getElementById('version-badge');
if (badge && d.version) badge.textContent = d.version;
})
.catch(() => {});
populateVersions();
fetch('/api/health')
.then(r => r.json())
.then(d => {
if (d && d.version) populateVersions(d.version);
})
.catch(() => {});
});
+33 -18
View File
@@ -1483,8 +1483,24 @@ export {
initAboutModal,
initProfile,
switchSidebarTab,
populateVersions,
};
// Populate every version display (header badge, About modal, help guide footer)
// from a single source of truth so they always match.
function populateVersions(version) {
var v = version || window.__OBSIGATE_VERSION || '—';
var els = [
document.getElementById('version-badge'),
document.getElementById('about-version'),
document.getElementById('help-version'),
];
for (var i = 0; i < els.length; i++) {
if (els[i]) els[i].textContent = v;
}
return v;
}
// ── Theme Picker ─────────────────────────────────────────────────────
function initThemePicker() {
import('./themes.js').then(function(mod) {
@@ -1656,24 +1672,23 @@ function initAboutModal() {
// Fallback silencieux : si le fetch échoue, on garde la version pré-chargée
// (window.__OBSIGATE_VERSION) au lieu d'un "—" trompeur.
fetch('/api/health')
.then(function(r) { return r.json(); })
.then(function(d) {
var fEl = document.getElementById('about-stat-files');
var vEl = document.getElementById('about-stat-vaults');
if (fEl && d.total_files) fEl.textContent = d.total_files;
if (vEl && d.vaults) vEl.textContent = d.vaults;
// Clean x.y.z version (not hardcoded) + git detail
var versionEl = document.getElementById('about-version');
if (versionEl) {
versionEl.textContent = (d && d.version) || window.__OBSIGATE_VERSION || '—';
}
var commitEl = document.getElementById('about-commit');
if (commitEl) commitEl.textContent = (d && d.git_describe) || (d && d.git_commit) || '—';
})
.catch(function() {
var versionEl = document.getElementById('about-version');
if (versionEl) versionEl.textContent = window.__OBSIGATE_VERSION || '—';
});
.then(function(r) { return r.json(); })
.then(function(d) {
var fEl = document.getElementById('about-stat-files');
var vEl = document.getElementById('about-stat-vaults');
if (fEl && d.total_files) fEl.textContent = d.total_files;
if (vEl && d.vaults) vEl.textContent = d.vaults;
// Single source of truth: populate the header badge, About and
// help-guide footer with the same version value.
if (d && (d.version || d.git_describe)) {
populateVersions((d && d.version) || window.__OBSIGATE_VERSION);
}
var commitEl = document.getElementById('about-commit');
if (commitEl) commitEl.textContent = (d && d.git_describe) || (d && d.git_commit) || '—';
})
.catch(function() {
populateVersions();
});
// Build date (today)
var now = new Date();
+33 -9
View File
@@ -1637,12 +1637,36 @@
"plugins.uninstalled": "Plugin '{name}' uninstalled.",
"plugins.confirm_uninstall": "Uninstall plugin '{name}'? This cannot be undone.",
"help.plugins_title": "🧩 Plugins",
"help.plugins_intro": "ObsiGate supports a plugin system to extend its functionality. Plugins can add custom renderers, search filters, editor actions, and UI elements.",
"help.plugins_install": "Installation",
"help.plugins_manage": "Management",
"help.plugins_develop": "Development",
"help.plugins_dev_intro": "A plugin is a folder or ZIP containing:",
"help.plugins_hooks_desc": "Available hooks: <code>onFileRender</code>, <code>onSearchFilter</code>, <code>onEditorAction</code>, <code>onSidebarItem</code>, <code>onFileCreate</code>, <code>onFileDelete</code>, <code>onVaultMount</code>.",
"help.plugins_security": "<strong>Security:</strong> each plugin runs in an isolated Web Worker sandbox, with no DOM, localStorage, or network access unless explicitly granted via permissions.",
"help.plugins_template": "Use the <strong>Template</strong> button in Settings > Plugins to generate a valid starter plugin."
}
"help.plugins_intro": "Plugins extend ObsiGate: custom file rendering, search filters, editor actions, widgets and integrations. They run in sandboxed Web Workers — isolated from the page for security.",
"help.plugins_install": "Installation",
"help.plugins_install_1": "Open Settings → 🧩 Plugins.",
"help.plugins_install_2": "Click 'Install a plugin'.",
"help.plugins_install_3": "Select a .zip file containing the plugin.json manifest and the plugin code.",
"help.plugins_install_4": "The manifest is validated (name, semver version, hooks, permissions) before installation.",
"help.plugins_manage": "Management",
"help.plugins_manage_1": "Enable / Disable: buttons on each plugin — hooks only run if the plugin is enabled.",
"help.plugins_manage_2": "Uninstall: permanently removes the plugin from the vault.",
"help.plugins_manage_3": "Code: view the source code of the installed plugin.",
"help.plugins_dev": "Develop a plugin",
"help.plugins_dev_intro": "Download the template from Settings → Plugins → 'Get template'. A plugin consists of a plugin.json manifest and a main file (e.g. index.js).",
"help.plugins_hooks": "Available hooks",
"help.plugins_hook_render": "onFileRender",
"help.plugins_hook_render_desc": "transforms the displayed content of a file.",
"help.plugins_hook_search": "onSearchFilter",
"help.plugins_hook_search_desc": "filters search results.",
"help.plugins_hook_editor": "onEditorAction",
"help.plugins_hook_editor_desc": "intercepts editor actions.",
"help.plugins_hook_sidebar": "onSidebarItem",
"help.plugins_hook_sidebar_desc": "adds items to the sidebar.",
"help.plugins_hook_file": "onFileCreate / onFileDelete",
"help.plugins_hook_file_desc": "reacts to file creation / deletion.",
"help.plugins_hook_vault": "onVaultMount",
"help.plugins_hook_vault_desc": "runs when a vault is loaded.",
"help.plugins_security": "Security",
"help.plugins_security_1": "Web Worker sandbox: plugin code runs isolated, with no direct DOM access.",
"help.plugins_security_2": "Permissions: each declared hook must be satisfied by the manifest permissions.",
"help.plugins_security_3": "Secure packaging: the .zip is checked against path traversal on install.",
"help.plugins_security_4": "Admin only: installation and removal require the admin role.",
"help.plugins_template": "Use the <strong>Template</strong> button in Settings > Plugins to generate a valid starter plugin.",
"help.footer_version": "ObsiGate <span id=\"help-version\"></span> - Web gateway for your Obsidian vaults"
}
+33 -9
View File
@@ -1637,12 +1637,36 @@
"plugins.uninstalled": "Plugin '{name}' désinstallé.",
"plugins.confirm_uninstall": "Désinstaller le plugin '{name}' ? Cette action est irréversible.",
"help.plugins_title": "🧩 Plugins",
"help.plugins_intro": "ObsiGate supporte un système de plugins pour étendre ses fonctionnalités. Les plugins peuvent ajouter des renderers personnalisés, des filtres de recherche, des actions d'éditeur, et des éléments d'interface.",
"help.plugins_install": "Installation",
"help.plugins_manage": "Gestion",
"help.plugins_develop": "Développement",
"help.plugins_dev_intro": "Un plugin est un dossier ou ZIP contenant :",
"help.plugins_hooks_desc": "Hooks disponibles : <code>onFileRender</code>, <code>onSearchFilter</code>, <code>onEditorAction</code>, <code>onSidebarItem</code>, <code>onFileCreate</code>, <code>onFileDelete</code>, <code>onVaultMount</code>.",
"help.plugins_security": "<strong>Sécurité :</strong> chaque plugin s'exécute dans un Web Worker isolé (sandbox), sans accès au DOM, localStorage, ni réseau sauf permissions explicites.",
"help.plugins_template": "Utilisez le bouton <strong>Template</strong> dans Paramètres > Plugins pour générer un plugin starter valide."
}
"help.plugins_intro": "Les plugins étendent ObsiGate : affichage personnalisé des fichiers, filtres de recherche, actions d'édition, widgets et intégrations. Ils s'exécutent dans des Web Workers sandboxés — isolés de la page pour la sécurité.",
"help.plugins_install": "Installation",
"help.plugins_install_1": "Ouvrez Réglages → 🧩 Plugins.",
"help.plugins_install_2": "Cliquez « Installer un plugin ».",
"help.plugins_install_3": "Sélectionnez un fichier .zip contenant le manifest plugin.json et le code du plugin.",
"help.plugins_install_4": "Le manifest est validé (nom, version semver, hooks, permissions) avant installation.",
"help.plugins_manage": "Gestion",
"help.plugins_manage_1": "Activer / Désactiver : boutons sur chaque plugin — les hooks ne tournent que si le plugin est activé.",
"help.plugins_manage_2": "Désinstaller : supprime définitivement le plugin du vault.",
"help.plugins_manage_3": "Code : visualisez le code source du plugin installé.",
"help.plugins_dev": "Développer un plugin",
"help.plugins_dev_intro": "Téléchargez le modèle depuis Réglages → Plugins → « Obtenir le modèle ». Un plugin se compose d'un manifest plugin.json et d'un fichier principal (ex. index.js).",
"help.plugins_hooks": "Hooks disponibles",
"help.plugins_hook_render": "onFileRender",
"help.plugins_hook_render_desc": "transforme le contenu affiché d'un fichier.",
"help.plugins_hook_search": "onSearchFilter",
"help.plugins_hook_search_desc": "filtre les résultats de recherche.",
"help.plugins_hook_editor": "onEditorAction",
"help.plugins_hook_editor_desc": "intercepte les actions de l'éditeur.",
"help.plugins_hook_sidebar": "onSidebarItem",
"help.plugins_hook_sidebar_desc": "ajoute des éléments à la barre latérale.",
"help.plugins_hook_file": "onFileCreate / onFileDelete",
"help.plugins_hook_file_desc": "réagit à la création / suppression de fichiers.",
"help.plugins_hook_vault": "onVaultMount",
"help.plugins_hook_vault_desc": "exécuté au chargement d'un vault.",
"help.plugins_security": "Sécurité",
"help.plugins_security_1": "Sandbox Web Worker : le code plugin tourne isolé, sans accès direct au DOM.",
"help.plugins_security_2": "Permissions : chaque hook déclaré doit être satisfait par les permissions du manifest.",
"help.plugins_security_3": "Empaquetage sécurisé : le .zip est vérifié contre le path traversal à l'installation.",
"help.plugins_security_4": "Admin uniquement : l'installation et la suppression requièrent le rôle admin.",
"help.plugins_template": "Utilisez le bouton <strong>Template</strong> dans Paramètres > Plugins pour générer un plugin starter valide.",
"help.footer_version": "ObsiGate <span id=\"help-version\"></span> - Porte d'entrée web pour vos vaults Obsidian"
}