From ffa07b7df4a05de42dc843bc8ef6546874b070c4 Mon Sep 17 00:00:00 2001 From: Bruno Charest Date: Thu, 10 Sep 2026 09:44:41 -0400 Subject: [PATCH] fix(ui,help): #61 unified dynamic version display + full guide sections for AI editor & plugins --- frontend/index.html | 77 +++++++++++++++++++++++++++++++++++++--- frontend/js/app.js | 19 +++++----- frontend/js/config.js | 51 ++++++++++++++++---------- frontend/locales/en.json | 42 +++++++++++++++++----- frontend/locales/fr.json | 42 +++++++++++++++++----- 5 files changed, 180 insertions(+), 51 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index ed692c1..d75ec02 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1455,8 +1455,6 @@
  • -
  • -
    @@ -2817,7 +2815,7 @@ >
  • - 🤖 IA Éditeur
  • @@ -2865,6 +2863,11 @@ data-i18n="help.nav_tips">đź’ˇ Astuces +
  • + đź§© Plugins +
  • @@ -4759,9 +4762,74 @@ curl -X POST https://votre-serveur.com/webhook \ + +
    +

    đź§© Plugins

    +

    + 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é. +

    + +

    Installation

    +
      +
    1. Ouvrez Réglages → 🧩 Plugins.
    2. +
    3. Cliquez « Installer un plugin ».
    4. +
    5. Sélectionnez un fichier .zip contenant le manifest + plugin.json + le code du plugin.
    6. +
    7. Le manifest est validé (nom, version semver, hooks, permissions) + avant installation.
    8. +
    + +

    Gestion

    +
      +
    • Activer / DĂ©sactiver : boutons sur chaque plugin — les + hooks ne tournent que si le plugin est activĂ©.
    • +
    • DĂ©sinstaller : supprime dĂ©finitivement le plugin du vault.
    • +
    • Code : visualisez le code source du plugin installĂ©.
    • +
    + +

    Développer un plugin

    +

    + 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). +

    + +

    Hooks disponibles

    +
      +
    • onFileRender : + transforme le contenu affichĂ© d'un fichier.
    • +
    • onSearchFilter : + filtre les rĂ©sultats de recherche.
    • +
    • onEditorAction : + intercepte les actions de l'Ă©diteur.
    • +
    • onSidebarItem : + ajoute des Ă©lĂ©ments Ă  la barre latĂ©rale.
    • +
    • onFileCreate / onFileDelete : + rĂ©agit Ă  la crĂ©ation / suppression de fichiers.
    • +
    • onVaultMount : + exĂ©cutĂ© au chargement d'un vault.
    • +
    + +

    Sécurité

    +
      +
    • Sandbox Web Worker : le code plugin tourne isolĂ©, sans + accès direct au DOM.
    • +
    • Permissions : chaque hook dĂ©clarĂ© doit ĂŞtre satisfait + par les permissions du manifest.
    • +
    • Empaquetage sĂ©curisĂ© : le .zip est vĂ©rifiĂ© contre le + path traversal Ă  l'installation.
    • +
    • Admin uniquement : l'installation et la suppression + requièrent le rĂ´le admin.
    • +
    +
    + +
    diff --git a/frontend/js/app.js b/frontend/js/app.js index 2345c2f..81e4ad4 100644 --- a/frontend/js/app.js +++ b/frontend/js/app.js @@ -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(() => {}); }); diff --git a/frontend/js/config.js b/frontend/js/config.js index 6371530..7ce4e19 100644 --- a/frontend/js/config.js +++ b/frontend/js/config.js @@ -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(); diff --git a/frontend/locales/en.json b/frontend/locales/en.json index 59d158b..5e2b788 100644 --- a/frontend/locales/en.json +++ b/frontend/locales/en.json @@ -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: onFileRender, onSearchFilter, onEditorAction, onSidebarItem, onFileCreate, onFileDelete, onVaultMount.", - "help.plugins_security": "Security: 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 Template button in Settings > Plugins to generate a valid starter plugin." -} \ No newline at end of file + "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 Template button in Settings > Plugins to generate a valid starter plugin.", + "help.footer_version": "ObsiGate - Web gateway for your Obsidian vaults" + } \ No newline at end of file diff --git a/frontend/locales/fr.json b/frontend/locales/fr.json index dabc576..4c118d3 100644 --- a/frontend/locales/fr.json +++ b/frontend/locales/fr.json @@ -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 : onFileRender, onSearchFilter, onEditorAction, onSidebarItem, onFileCreate, onFileDelete, onVaultMount.", - "help.plugins_security": "Sécurité : 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 Template dans Paramètres > Plugins pour générer un plugin starter valide." -} \ No newline at end of file + "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 Template dans Paramètres > Plugins pour générer un plugin starter valide.", + "help.footer_version": "ObsiGate - Porte d'entrée web pour vos vaults Obsidian" + } \ No newline at end of file