feat: add initial frontend SPA for vault browsing, advanced search, and markdown rendering.

This commit is contained in:
Bruno Charest 2026-03-27 21:29:22 -04:00
parent e91cc1c52c
commit 9e1b4f4105
3 changed files with 90 additions and 33 deletions

View File

@ -3,6 +3,8 @@
(function () { (function () {
"use strict"; "use strict";
const APP_VERSION = "1.5.0";
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// State // State
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -4762,29 +4764,68 @@
function showWelcome() { function showWelcome() {
hideProgressBar(); hideProgressBar();
// Ensure the dashboard container exists (it might have been wiped by renderFile) // Ensure the dashboard container exists and has the correct structure (it might have been wiped by renderFile or be an old version)
const area = document.getElementById("content-area"); const area = document.getElementById("content-area");
if (area && !document.getElementById("dashboard-home")) { const home = document.getElementById("dashboard-home");
const bookmarksSection = document.getElementById("dashboard-bookmarks-section");
if (area && (!home || !bookmarksSection)) {
area.innerHTML = ` area.innerHTML = `
<div id="dashboard-home" class="dashboard-home" role="region" aria-label="Derniers fichiers ouverts"> <div id="dashboard-home" class="dashboard-home" role="region" aria-label="Tableau de bord">
<div class="dashboard-header"> <!-- Bookmarks Section -->
<div class="dashboard-title-row"> <div id="dashboard-bookmarks-section" class="dashboard-section">
<i data-lucide="clock" class="dashboard-icon"></i> <div class="dashboard-header">
<h2>Derniers fichiers ouverts</h2> <div class="dashboard-title-row">
<i data-lucide="bookmark" class="dashboard-icon" style="color:var(--accent-green)"></i>
<h2>Bookmarks</h2>
</div>
</div>
<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>Épinglez des fichiers pour les retrouver ici.</p>
</div> </div>
</div> </div>
<div id="dashboard-recent-grid" class="dashboard-recent-grid"></div>
<div id="dashboard-loading" class="dashboard-loading"> <!-- Recently Opened Section -->
<div class="skeleton-card"></div> <div id="dashboard-recent-section" class="dashboard-section">
<div class="skeleton-card"></div> <div class="dashboard-header">
<div class="skeleton-card"></div> <div class="dashboard-title-row">
</div> <i data-lucide="clock" class="dashboard-icon"></i>
<div id="dashboard-bookmarks-empty" class="dashboard-recent-empty hidden"> <h2>Derniers fichiers ouverts</h2>
<i data-lucide="pin"></i> <span id="dashboard-count" class="dashboard-badge"></span>
<span>Aucun bookmark</span> </div>
<p>Épinglez des fichiers pour les retrouver ici.</p> <div class="dashboard-actions">
<select id="dashboard-vault-filter" class="dashboard-filter" aria-label="Filtrer par vault">
<option value="all">Tous les vaults</option>
</select>
</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>Aucun fichier récent</span>
<p>Ouvrez un fichier pour le voir apparaître ici</p>
</div>
</div> </div>
</div>`; </div>`;
// Re-initialize widgets which might need to bind events to new elements
if (typeof DashboardRecentWidget !== "undefined") {
DashboardRecentWidget.init();
}
safeCreateIcons(); safeCreateIcons();
} }
@ -5825,6 +5866,8 @@
initCustomDropdowns(); initCustomDropdowns();
document.getElementById("theme-toggle").addEventListener("click", toggleTheme); document.getElementById("theme-toggle").addEventListener("click", toggleTheme);
document.getElementById("header-logo").addEventListener("click", goHome); document.getElementById("header-logo").addEventListener("click", goHome);
const refreshBtn = document.getElementById("header-refresh-btn");
if (refreshBtn) refreshBtn.addEventListener("click", goHome);
initSearch(); initSearch();
initSidebarToggle(); initSidebarToggle();
initMobile(); initMobile();
@ -5848,6 +5891,11 @@
try { try {
await Promise.all([loadVaultSettings(), loadVaults(), loadTags()]); await Promise.all([loadVaultSettings(), loadVaults(), loadTags()]);
// Initialize dashboard widgets now that vaults are loaded
if (typeof DashboardRecentWidget !== "undefined") {
DashboardRecentWidget.init();
}
// Check for popup mode query parameter // Check for popup mode query parameter
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get("popup") === "true") { if (urlParams.get("popup") === "true") {
@ -5863,6 +5911,9 @@
const path = decodeURIComponent(hashVal.substring(sepIndex + 1)); const path = decodeURIComponent(hashVal.substring(sepIndex + 1));
openFile(vault, path); openFile(vault, path);
} }
} else if (urlParams.get("popup") !== "true") {
// Default to dashboard if no deep link and not in popup mode
showWelcome();
} }
} catch (err) { } catch (err) {
console.error("Failed to initialize ObsiGate:", err); console.error("Failed to initialize ObsiGate:", err);
@ -5958,9 +6009,5 @@
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
init(); init();
registerServiceWorker(); registerServiceWorker();
// Initialize the dashboard recent files widget
if (typeof DashboardRecentWidget !== "undefined") {
DashboardRecentWidget.init();
}
}); });
})(); })();

View File

@ -373,21 +373,31 @@
<div class="dashboard-title-row"> <div class="dashboard-title-row">
<i data-lucide="clock" class="dashboard-icon"></i> <i data-lucide="clock" class="dashboard-icon"></i>
<h2>Derniers fichiers ouverts</h2> <h2>Derniers fichiers ouverts</h2>
<span id="dashboard-count" class="dashboard-badge"></span>
</div>
<div class="dashboard-actions">
<select id="dashboard-vault-filter" class="dashboard-filter" aria-label="Filtrer par vault">
<option value="all">Tous les vaults</option>
</select>
</div> </div>
</div> </div>
<div id="dashboard-recent-grid" class="dashboard-recent-grid"></div> <div id="dashboard-recent-grid" class="dashboard-recent-grid"></div>
<div id="dashboard-loading" class="dashboard-loading"> <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 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>
<div id="dashboard-recent-empty" class="dashboard-recent-empty hidden">
<i data-lucide="inbox"></i> <div id="dashboard-recent-empty" class="dashboard-recent-empty hidden">
<span>Aucun fichier récent</span> <i data-lucide="inbox"></i>
<p>Ouvrez un fichier pour le voir apparaître ici</p> <span>Aucun fichier récent</span>
<p>Ouvrez un fichier pour le voir apparaître ici</p>
</div>
</div> </div>
</div> </div>
</main> </main>

View File

@ -1,6 +1,6 @@
/* ObsiGate Service Worker - PWA Support */ /* ObsiGate Service Worker - PWA Support */
const CACHE_VERSION = 'obsigate-v1.4.0'; const CACHE_VERSION = 'obsigate-v1.5.0';
const STATIC_CACHE = `${CACHE_VERSION}-static`; const STATIC_CACHE = `${CACHE_VERSION}-static`;
const DYNAMIC_CACHE = `${CACHE_VERSION}-dynamic`; const DYNAMIC_CACHE = `${CACHE_VERSION}-dynamic`;
const MAX_DYNAMIC_CACHE_SIZE = 50; const MAX_DYNAMIC_CACHE_SIZE = 50;