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
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:
+73
-4
@@ -1455,8 +1455,6 @@
|
|||||||
<li><a href="#cfg-webhooks" class="help-nav-link" data-i18n="config.section_webhooks"></a></li>
|
<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>
|
<li><a href="#cfg-partages-publics" class="help-nav-link" data-i18n="config.section_shares"></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<li>
|
|
||||||
<a href="#help-plugins" class="help-nav-link"
|
|
||||||
</nav>
|
</nav>
|
||||||
<div class="help-content" id="config-scroll">
|
<div class="help-content" id="config-scroll">
|
||||||
<div class="config-content">
|
<div class="config-content">
|
||||||
@@ -2817,7 +2815,7 @@
|
|||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<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
|
data-i18n="help.nav_ai">🤖 IA Éditeur</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
@@ -2865,6 +2863,11 @@
|
|||||||
data-i18n="help.nav_tips">💡 Astuces</a
|
data-i18n="help.nav_tips">💡 Astuces</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#help-plugins" class="help-nav-link"
|
||||||
|
data-i18n="help.nav_plugins">🧩 Plugins</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="help-content">
|
<div class="help-content">
|
||||||
@@ -4759,9 +4762,74 @@ curl -X POST https://votre-serveur.com/webhook \
|
|||||||
</ul>
|
</ul>
|
||||||
</section>
|
</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">
|
<div class="help-footer">
|
||||||
<p>
|
<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
|
d'entrée web pour vos vaults Obsidian
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
@@ -4773,6 +4841,7 @@ curl -X POST https://votre-serveur.com/webhook \
|
|||||||
>.
|
>.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+8
-11
@@ -23,6 +23,7 @@ import PaneManager from './pane-manager.js';
|
|||||||
import { initDesktopIntegration, isTauriEnv } from './desktop.js';
|
import { initDesktopIntegration, isTauriEnv } from './desktop.js';
|
||||||
import { initPush } from './push.js';
|
import { initPush } from './push.js';
|
||||||
import { initPlugins } from './plugins.js';
|
import { initPlugins } from './plugins.js';
|
||||||
|
import { populateVersions } from './config.js';
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// Initialization — mirrors the original app.js init() ordering
|
// Initialization — mirrors the original app.js init() ordering
|
||||||
@@ -123,15 +124,11 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
if (typeof window.__obsigateBootReady === "function") window.__obsigateBootReady();
|
if (typeof window.__obsigateBootReady === "function") window.__obsigateBootReady();
|
||||||
}
|
}
|
||||||
// Show version in header — always visible, fallback before the async fetch
|
// Show version in header — always visible, fallback before the async fetch
|
||||||
const versionBadge = document.getElementById('version-badge');
|
populateVersions();
|
||||||
if (versionBadge) {
|
fetch('/api/health')
|
||||||
versionBadge.textContent = window.__OBSIGATE_VERSION || '…';
|
.then(r => r.json())
|
||||||
}
|
.then(d => {
|
||||||
fetch('/api/health')
|
if (d && d.version) populateVersions(d.version);
|
||||||
.then(r => r.json())
|
})
|
||||||
.then(d => {
|
.catch(() => {});
|
||||||
const badge = document.getElementById('version-badge');
|
|
||||||
if (badge && d.version) badge.textContent = d.version;
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
});
|
});
|
||||||
|
|||||||
+33
-18
@@ -1483,8 +1483,24 @@ export {
|
|||||||
initAboutModal,
|
initAboutModal,
|
||||||
initProfile,
|
initProfile,
|
||||||
switchSidebarTab,
|
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 ─────────────────────────────────────────────────────
|
// ── Theme Picker ─────────────────────────────────────────────────────
|
||||||
function initThemePicker() {
|
function initThemePicker() {
|
||||||
import('./themes.js').then(function(mod) {
|
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
|
// Fallback silencieux : si le fetch échoue, on garde la version pré-chargée
|
||||||
// (window.__OBSIGATE_VERSION) au lieu d'un "—" trompeur.
|
// (window.__OBSIGATE_VERSION) au lieu d'un "—" trompeur.
|
||||||
fetch('/api/health')
|
fetch('/api/health')
|
||||||
.then(function(r) { return r.json(); })
|
.then(function(r) { return r.json(); })
|
||||||
.then(function(d) {
|
.then(function(d) {
|
||||||
var fEl = document.getElementById('about-stat-files');
|
var fEl = document.getElementById('about-stat-files');
|
||||||
var vEl = document.getElementById('about-stat-vaults');
|
var vEl = document.getElementById('about-stat-vaults');
|
||||||
if (fEl && d.total_files) fEl.textContent = d.total_files;
|
if (fEl && d.total_files) fEl.textContent = d.total_files;
|
||||||
if (vEl && d.vaults) vEl.textContent = d.vaults;
|
if (vEl && d.vaults) vEl.textContent = d.vaults;
|
||||||
// Clean x.y.z version (not hardcoded) + git detail
|
// Single source of truth: populate the header badge, About and
|
||||||
var versionEl = document.getElementById('about-version');
|
// help-guide footer with the same version value.
|
||||||
if (versionEl) {
|
if (d && (d.version || d.git_describe)) {
|
||||||
versionEl.textContent = (d && d.version) || window.__OBSIGATE_VERSION || '—';
|
populateVersions((d && d.version) || window.__OBSIGATE_VERSION);
|
||||||
}
|
}
|
||||||
var commitEl = document.getElementById('about-commit');
|
var commitEl = document.getElementById('about-commit');
|
||||||
if (commitEl) commitEl.textContent = (d && d.git_describe) || (d && d.git_commit) || '—';
|
if (commitEl) commitEl.textContent = (d && d.git_describe) || (d && d.git_commit) || '—';
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
var versionEl = document.getElementById('about-version');
|
populateVersions();
|
||||||
if (versionEl) versionEl.textContent = window.__OBSIGATE_VERSION || '—';
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Build date (today)
|
// Build date (today)
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
|
|||||||
@@ -1637,12 +1637,36 @@
|
|||||||
"plugins.uninstalled": "Plugin '{name}' uninstalled.",
|
"plugins.uninstalled": "Plugin '{name}' uninstalled.",
|
||||||
"plugins.confirm_uninstall": "Uninstall plugin '{name}'? This cannot be undone.",
|
"plugins.confirm_uninstall": "Uninstall plugin '{name}'? This cannot be undone.",
|
||||||
"help.plugins_title": "🧩 Plugins",
|
"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_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": "Installation",
|
||||||
"help.plugins_manage": "Management",
|
"help.plugins_install_1": "Open Settings → 🧩 Plugins.",
|
||||||
"help.plugins_develop": "Development",
|
"help.plugins_install_2": "Click 'Install a plugin'.",
|
||||||
"help.plugins_dev_intro": "A plugin is a folder or ZIP containing:",
|
"help.plugins_install_3": "Select a .zip file containing the plugin.json manifest and the plugin code.",
|
||||||
"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_install_4": "The manifest is validated (name, semver version, hooks, permissions) before installation.",
|
||||||
"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_manage": "Management",
|
||||||
"help.plugins_template": "Use the <strong>Template</strong> button in Settings > Plugins to generate a valid starter plugin."
|
"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"
|
||||||
|
}
|
||||||
@@ -1637,12 +1637,36 @@
|
|||||||
"plugins.uninstalled": "Plugin '{name}' désinstallé.",
|
"plugins.uninstalled": "Plugin '{name}' désinstallé.",
|
||||||
"plugins.confirm_uninstall": "Désinstaller le plugin '{name}' ? Cette action est irréversible.",
|
"plugins.confirm_uninstall": "Désinstaller le plugin '{name}' ? Cette action est irréversible.",
|
||||||
"help.plugins_title": "🧩 Plugins",
|
"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_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": "Installation",
|
||||||
"help.plugins_manage": "Gestion",
|
"help.plugins_install_1": "Ouvrez Réglages → 🧩 Plugins.",
|
||||||
"help.plugins_develop": "Développement",
|
"help.plugins_install_2": "Cliquez « Installer un plugin ».",
|
||||||
"help.plugins_dev_intro": "Un plugin est un dossier ou ZIP contenant :",
|
"help.plugins_install_3": "Sélectionnez un fichier .zip contenant le manifest plugin.json et le code du plugin.",
|
||||||
"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_install_4": "Le manifest est validé (nom, version semver, hooks, permissions) avant installation.",
|
||||||
"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_manage": "Gestion",
|
||||||
"help.plugins_template": "Utilisez le bouton <strong>Template</strong> dans Paramètres > Plugins pour générer un plugin starter valide."
|
"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"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user