Commit Graph
501 Commits
Author SHA1 Message Date
bruno 03e115b65b feat: #75 complété — 5 dernières sous-tâches implémentées
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 12s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
C1b: Sous-menu « Déplacer vers... » (flyout hover) — liste les autres panneaux
D2: Drag depuis l'arborescence vers panneau — format 'tree:{vault,path}'
E3: Rendu paresseux — display:none sur contenu des panneaux inactifs
E4: Verrouillage éditeur — même fichier déjà ouvert → focus le panneau existant
G3: Bouton reset (🔄 Réinitialiser les panneaux) dans la palette

ROADMAP: section 75 marquée ✅ Complété (reste I2/I3 tests)
2026-07-28 10:15:50 -04:00
bruno 804e6313b3 feat: finalisation split view #75 — boutons, nav clavier, palette, ROADMAP
CI / lint (push) Failing after 12s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 13s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
Ajouts:
- C3: Boutons Split ⊞→ ⊞↓ dans la barre d'onglets (visibles au survol)
- C2: Ctrl+Alt+←/→/↑/↓ navigation entre panneaux
- C2: Ctrl+Shift+Alt+W fermer tous les autres panneaux
- H1: 5 commandes palette (Split R/D, Close Pane, Focus Next/Prev)
- ROADMAP.md: section 75 mise à jour avec statut 80% complété

CSS: .tab-split-buttons, .tab-split-btn avec opacity hover
2026-07-28 10:08:11 -04:00
bruno ed5cf597f9 fix: migration des onglets singleton → PaneTabManager au split
CI / lint (push) Failing after 13s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 15s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
_buildGrid: quand on passe de single-pane à multi-pane, migre les onglets
du TabManager singleton vers le PaneTabManager du pane 0.
Sans ça, transferTab() ne trouvait pas l'onglet (il était resté dans le singleton).

_collapseToSingle: migration inverse (PaneTabManager → singleton)
quand on ferme le dernier split.
2026-07-27 23:34:06 -04:00
bruno 4deb54b3a3 fix: dragstart singleton TabManager — JSON au lieu de String(idx)
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 16s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
Cause: le TabManager singleton (single-pane) écrasait text/plain avec String(idx)
→ getData retournait '1' au lieu du JSON {paneId,tabId,index}
→ le drop handler PaneManager échouait sur 'missing paneId/tabId'

Fix:
- singleton dragstart: JSON.stringify({paneId:0, tabId, index}) + effectAllowed
- singleton drop: parse JSON, fallback legacy parseInt pour rétrocompatibilité
- dragover/drop inchangés (indicateurs visuels)
2026-07-27 23:28:39 -04:00
bruno fe4cb9c47c fix: drag-drop utilise text/plain uniquement + logs console
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 16s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- dragstart: setData 'text/plain' (universel, pas de custom MIME)
- drop container + tab: getData('text/plain')
- console.log dans le drop handler pour diagnostic
- Suppression application/obsigate-tab (non fiable cross-browser)
2026-07-27 23:20:55 -04:00
bruno 1a9a555bee fix: bookmarks/récents utilisent TabManager + drag-to-split corrigé
CI / lint (push) Failing after 10s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 15s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
Bug 1 — bookmarks/récents sans tab:
  dashboard.js:135: openFile() → TabManager.openPreview()
  _createCard() est partagé par DashboardRecentWidget ET DashboardBookmarkWidget

Bug 2 — drag-to-split bloqué en single-pane:
  La condition 'if (dragData.paneId === paneId) return' empêchait le split
  car en single-pane, le drag part du pane 0 et drop sur le pane 0.
  → Supprimé. Edge detection vérifiée avant, cross-pane vérifié après.
  Même pane + pas edge → laissé au tab handler (reorder).
2026-07-27 23:04:51 -04:00
bruno d7b0998af8 fix: drag-to-split — drop zone sur .content-wrapper en mode single-pane
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 14s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
Cause: _setupPaneDropZone était uniquement appelé sur .pane-container (créé par split).
En mode single-pane, le DOM est .content-wrapper > .tab-bar + .content-area sans wrapper.
→ Ajout de _setupPaneDropZone sur .content-wrapper dans PaneManager.init()
→ CSS: position:relative sur .content-wrapper pour les indicateurs absolute

Changements:
- pane-manager.js: init() ajoute drop zone sur .content-wrapper (single-pane)
- style.css: position:relative sur .content-wrapper
2026-07-27 22:50:46 -04:00
bruno 8aaf19479f fix: drag-to-split — supprimé filtre types + ajout effectAllowed + fallback text/plain
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 29s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- dragstart: effectAllowed='move' + double setData (obsigate-tab + text/plain)
- dragenter/dragover: acceptent TOUS les drags (plus de filtre types.includes cassant)
- drop: fallback text/plain si application/obsigate-tab indisponible
- console.debug au lieu de silent catch pour diagnostiquer les erreurs restantes
2026-07-27 22:48:48 -04:00
bruno 069d119d03 fix: drag & drop corrigé — 3 bugs critiques résolus
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 15s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
1. types.includes → Array.from(types).includes (DOMStringList n'a pas .includes)
2. dragleave: compteur _dragCounter empêche clear sur child enter/leave
3. drag-to-split: zone recalculée dans drop handler (plus de closure corrompue)
4. drop: stopPropagation + skip same-paneId dans container handler
5. dragenter: appel preventDefault pour accepter le drop dès l'entrée
2026-07-27 22:42:45 -04:00
bruno a842d68038 feat: drop cross-pane fonctionnel + drag-to-split (bord droit/bas)
CI / lint (push) Failing after 12s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 16s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- _setupPaneDropZone: dragover/drop sur .pane-container (fonctionne même si tab bar vide)
- Drag-to-split: déposer un onglet dans les 25% droit → split right, 25% bas → split down
- Indicateurs visuels: zone bleue semi-transparente au drop, tab-bar dashed outline
- stopPropagation dans le drop handler des tabs pour éviter double-fire
- CSS: .pane-drop-zone-indicator, .tab-bar.drop-target, position:relative sur pane-container
2026-07-27 22:16:04 -04:00
bruno e5cd656c6e fix: TabManager exposé sur window + fermeture auto du panneau vide
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 20s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- ui.js: window.TabManager et window._singletonTabManager exposés dans init()
- pane-manager.js: référence corrigée vers window.TabManager (n'était pas en scope)
- PaneTabManager.close/transferTabTo: ferme automatiquement le panneau quand vide (sauf dernier)
- Déployé sur 192.168.30.101:2020, 307 tests verts
2026-07-27 21:51:19 -04:00
bruno ed4c1dcf07 feat: split view pro — TabManager indépendant par panneau avec drag & drop cross-pane
CI / lint (push) Failing after 10s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 17s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- PaneTabManager factory: chaque panneau a sa propre instance avec ses propres onglets
- Drag & drop d'onglets entre panneaux (application/obsigate-tab dataTransfer)
- Split copie l'onglet actif dans le nouveau panneau
- TabManager singleton: délégation automatique vers le panneau actif en mode split
- Persistance complète par panneau (tabs, activeTab, previewTab)
- viewer.js: getContentArea() priorise window._activePaneContentArea
- 307 tests verts, déployé sur 192.168.30.101:2020
2026-07-27 21:37:04 -04:00
bruno b27b38d32b feat: split view multi-panneaux (#75) — PaneManager intégré avec split right/down, menu contextuel, raccourcis clavier, CSS responsive et tests
CI / lint (push) Failing after 35s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 15s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- PaneManager: splitRight/splitDown avec 1-4 panneaux, persistance localStorage, resize
- Viewer/TabManager pane-aware: fonctions getContentArea/getTabBar/getTabList
- Menu contextuel onglets: actions Diviser à droite / Diviser en bas / Fermer le panneau
- Raccourcis clavier: Ctrl+Alt+\ (split right), Ctrl+Alt+Shift+\ (split down), Ctrl+Alt+W (fermer panneau)
- CSS pane-grid: grille, poignées resize, bordure active pane, responsive (désactivé <768px)
- Tests: 22 nouveaux tests unitaires + régression (307 total, 100% green)
- Déployé sur Docker test (localhost:2021)
2026-07-27 21:06:47 -04:00
bruno 0cea78b3b1 feat: badge version dans le header + tag v2.0.0-dev
CI / lint (push) Failing after 9s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 13s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- index.html: <div class="version-badge"> dans header-right
- app.js: fetch /api/health → affiche version dans le badge
- style.css: .version-badge discret (10px, mono, muted)
- Tag: v2.0.0-dev créé → git describe retourne v2.0.0-dev
2026-07-27 18:02:01 -04:00
bruno e213ad183e feat: support multi-format — images, CSV, JSON, TXT + fix PDF embed
CI / lint (push) Failing after 19s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 14s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- PDF: <iframe> → <embed> (plus compatible webview Tauri)
- Images: .png .jpg .gif .svg .webp .bmp .ico → rendu standalone avec toolbar
- CSV: rendu en tableau HTML avec headers sticky
- JSON: affichage formaté avec indentation (html.escape)
- Texte: .txt .log .yml .yaml .py .js .sh .toml .ini → <pre> mono
- CSS: .image-viewer-body, .csv-table, .text-viewer, .json-viewer, .file-toolbar
2026-07-27 15:06:24 -04:00
bruno 2ba7138881 feat: affichage PDF avec TOC + frame-src CSP
CI / lint (push) Successful in 23s
CI / security (push) Successful in 14s
CI / test (push) Successful in 27s
CI / build (push) Successful in 8s
CI / e2e (push) Failing after 1m29s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- CSP: ajout frame-src 'self' http://127.0.0.1:* (permet iframe PDF)
- pdf_reader.py: extract_pdf_toc() — extrait les bookmarks/outline (pypdf + pymupdf)
- main.py: inclut pdf_toc dans la réponse /api/file pour les PDF
- viewer.js: sidebar TOC avec liens vers les pages (si bookmarks présents)
- style.css: layout .pdf-body flex + .pdf-toc sidebar 240px
2026-07-27 12:32:11 -04:00
bruno ec32030afc fix: always show copy button on mobile (no hover on touch)
CI / lint (push) Successful in 30s
CI / security (push) Successful in 13s
CI / test (push) Successful in 28s
CI / build (push) Successful in 8s
CI / e2e (push) Failing after 21s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- @media (max-width: 768px): .copy-code-btn opacity: 1
- Smaller padding/font on mobile (2px 8px, 10px font)
- Tighter position (top: 4px, right: 4px) to avoid overlapping content
2026-07-25 13:04:34 -04:00
bruno 553e1dd4ee fix: add copyToClipboard import in viewer.js
CI / lint (push) Successful in 24s
CI / security (push) Successful in 14s
CI / test (push) Successful in 29s
CI / build (push) Successful in 7s
CI / e2e (push) Failing after 25s
Desktop Build / build-windows (push) Has been cancelled
Desktop Build / build-linux (push) Has been cancelled
- Was missing from utils.js import → ReferenceError
2026-07-25 10:36:42 -04:00
bruno cdaea4142b fix: remove duplicate safeHighlight declaration in utils.js
- Caused 'Identifier already declared' error — app won't load
- Original safeHighlight at line 250 (initEditor scope), duplicate removed
2026-07-25 10:35:18 -04:00
bruno 5426022273 fix: HTTP fallback for clipboard — execCommand('copy') textarea method
- Added copyToClipboard() in utils.js with dual strategy:
  - HTTPS: navigator.clipboard.writeText() (modern API)
  - HTTP: textarea + execCommand('copy') (legacy fallback)
- viewer.js: uses copyToClipboard() instead of direct navigator.clipboard
- popout.html: same dual-strategy inline
- Fixed: 'Erreur lors de la copie' on HTTP contexts
2026-07-25 10:32:39 -04:00
bruno 15a217eca4 feat: add copy-to-clipboard button on code blocks in viewer + popout
- CSS: .code-block-wrapper with relative positioning
- CSS: .copy-code-btn with hover opacity transition (hidden until hover)
- CSS: .copied state (green accent) after successful copy
- viewer.js: wraps each <pre> in .code-block-wrapper + appends copy button
- popout.html: same logic with vanilla JS (ES5 compatible)
- Button: 'Copier' → '✓ Copié' on click, reverts after 2s
- Toast: showToast('Code copié dans le presse-papiers') via navigator.clipboard
2026-07-25 10:27:40 -04:00
bruno b09a642f66 fix: copy ALL CSS custom properties via getComputedStyle from opener
CI / lint (push) Successful in 23s
CI / security (push) Successful in 13s
CI / test (push) Successful in 31s
CI / build (push) Successful in 9s
CI / e2e (push) Failing after 29s
- Iterates through ALL computed CSS variables (--*) from main app
- Uses getComputedStyle which works even if setProperty was used (themes.js)
- Sets properties via setProperty on popout root — EXACT theme match
- Fallback: localStorage obsigate-theme-mode for direct popout access
- Fixed typo in --text-primary (was 'teext-primary')
2026-07-24 15:36:00 -04:00
bruno 21ee86ffa0 fix: popout inherits exact theme via opener window inline styles
CI / lint (push) Successful in 24s
CI / security (push) Successful in 14s
CI / test (push) Successful in 30s
CI / build (push) Successful in 18s
CI / e2e (push) Failing after 38s
- Copies documentElement.style.cssText from main app (has all CSS variables from themes.js setProperty)
- This propagates ANY theme (Github, Linear, Spotify, Notion, etc.) dark+light
- Fallback: localStorage obsigate-theme + obsigate-theme-mode for direct popout access
- Removes the !important hack — replaced by proper cssText inheritance
2026-07-24 15:35:17 -04:00
bruno 02396641f6 fix: force theme via inline style as ultimate fallback
CI / lint (push) Successful in 23s
CI / security (push) Successful in 13s
CI / test (push) Successful in 32s
CI / build (push) Successful in 7s
CI / e2e (push) Failing after 15s
- Added <style id='theme-force'> with !important dark theme defaults
- JS updates inline style for light mode
- Completely bypasses CSS variable loading, caching, or path issues
- Guarantees body bg/text color regardless of stylesheet state
2026-07-24 15:01:04 -04:00
bruno a583281edb fix: add cache-buster to popout style.css URL
CI / lint (push) Successful in 27s
CI / security (push) Successful in 13s
CI / test (push) Successful in 27s
CI / build (push) Successful in 12s
CI / e2e (push) Failing after 19s
- Changed /static/style.css to /static/style.css?v=2 to force fresh load
- Ensures popout gets the latest CSS with dark theme :root defaults
2026-07-24 14:59:46 -04:00
bruno 8b950a8031 fix: dark theme as default in :root — no data-theme dependency
CI / lint (push) Successful in 23s
CI / security (push) Successful in 13s
CI / test (push) Successful in 34s
CI / build (push) Successful in 8s
CI / e2e (push) Failing after 22s
- Added full dark theme variables to bare :root selector (no attribute required)
- This ensures dark theme always loads even if data-theme is not set or stripped
- :root[data-theme='light'] still overrides for light mode
- Popout windows now always get dark theme baseline
2026-07-24 14:57:45 -04:00
bruno a1355977d9 fix: popout theme inheritance via URL query param
CI / lint (push) Successful in 24s
CI / security (push) Successful in 14s
CI / test (push) Successful in 28s
CI / build (push) Successful in 18s
CI / e2e (push) Failing after 10s
- Pass current theme as ?theme=dark|light in popout URL
- viewer.js, app.js, palette.js all pass theme to popout
- popout.html reads theme from URL param first (fallback: localStorage, then dark)
- Also syncs theme back to localStorage when set via query param
2026-07-24 14:56:29 -04:00
bruno f3bfd01f93 fix: popout Mermaid rendering order — run before highlight.js
CI / lint (push) Successful in 22s
CI / security (push) Successful in 14s
CI / test (push) Successful in 29s
CI / build (push) Successful in 8s
CI / e2e (push) Failing after 15s
- Mermaid now initializes and renders BEFORE highlight.js processes code blocks
- highlight.js skips .language-mermaid blocks to avoid 'Could not find language' warnings
- Code highlighting runs after Mermaid SVG replaces the code block
- Removes duplicate/conflicting hljs calls
2026-07-24 14:45:13 -04:00
bruno 143b1d436b fix: popout window — theme, Mermaid, frontmatter parity with main app
CI / lint (push) Successful in 27s
CI / security (push) Successful in 13s
CI / test (push) Successful in 28s
CI / build (push) Successful in 8s
CI / e2e (push) Failing after 26s
- Added Mermaid CDN script + mermaid.initialize() with theme detection
- Frontmatter card now collapsed by default (matching main app isOpen=false)
- Hidden acCard initially when collapsed
- Theme inherits localStorage obsigate-theme (same as main window)
2026-07-24 14:22:45 -04:00
bruno 6c448b3060 fix: frontend unit tests — add type:module in frontend/js/
CI / lint (push) Failing after 34s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Successful in 14s
- Root package.json has type:commonjs which breaks ES module syntax checks
- Added frontend/js/package.json with type:module for Node.js parsing
- All 27 JS modules now parse correctly in CI environment
2026-07-24 11:37:22 -04:00
bruno 88b73f663f fix: header logout button dynamically recreated by renderUserMenu
- renderUserMenu() rebuilds #logout-btn with innerHTML, wiping inline onclick
- Added onclick='window.handleLogout()' to the dynamic innerHTML string
- Restored addEventListener as double safety
- Settings #profile-logout already has onclick to handleLogout
2026-07-24 10:04:13 -04:00
bruno 8bbf973097 fix: proper logout via window.handleLogout with XHR fallback
- Both buttons call window.handleLogout (AuthManager.logout) or doLogoutFallback
- doLogoutFallback: XHR POST, hides #app, shows #login-screen, clears token
- No more localStorage.clear() or hard redirect — mimics showLoginScreen()
- Removed all conflicting JS event listeners
2026-07-24 10:03:10 -04:00
bruno 14a45c9136 fix: remove remaining logout JS handler in config.js 2026-07-24 09:56:15 -04:00
bruno d2dec1be06 fix: both logout buttons now use inline onclick — no JS handlers
- Header #logout-btn: inline fetch+clear localStorage+redirect
- Settings #profile-logout: inline window.handleLogout or fetch fallback
- Removed all JS event listeners that were causing race conditions
- Zero dependency on ES module loading order
2026-07-24 09:55:43 -04:00
bruno 317065f986 fix: settings logout via inline onclick — bypasses ES module race
- profile-logout now handles logout directly via onclick attribute in HTML
- Calls window.handleLogout() (auth.js global) or direct fetch fallback
- Removed broken JS handler from config.js to avoid double execution
2026-07-24 09:54:42 -04:00
bruno 24b56ac0e7 fix: missing closing brace in config.js causing SyntaxError
- Brace balance was 403 opens vs 402 closes after logout handler patches
- Added missing closing brace — file now parses correctly
2026-07-24 09:52:51 -04:00
bruno b46b98c5a7 fix: settings logout buttons now call AuthManager.logout() directly
- Replaced window.handleLogout indirection with direct AuthManager.logout() call
- config.js already imports AuthManager from auth.js — no race condition
- Same direct call as header button (auth.js line 210)
2026-07-24 09:50:15 -04:00
bruno 3655ef8a7e fix: TOC panel never auto-opens on login — always starts closed
- Removed localStorage restore of obsigate-right-sidebar-visible on init
- TOC only opens when user clicks the TOC button in a document
- Width preference still restored from localStorage
2026-07-24 09:43:37 -04:00
bruno 3cf1c33b69 fix: remove confirm() dialogs from both logout buttons
- Header logout (#logout-btn) already had no confirm (AuthManager.logout called directly)
- Settings panel (#logout-btn + #profile-logout) now call handleLogout() without confirm
- Both buttons redirect to login screen immediately — consistent behavior
2026-07-24 09:36:23 -04:00
bruno 61caa47745 fix: logout button in settings panel now properly clears session
- Both #logout-btn and #profile-logout now delegate to window.handleLogout()
- Previously they did bare fetch+redirect without clearing JWT token or session state
- Added credentials: 'include' fallback for robustness
2026-07-24 09:27:54 -04:00
bruno 797d9763dd fix: TOC sidebar closed by default on initial load
- Changed rightSidebarVisible default from true to false
- First-time visitors no longer see the TOC panel auto-opened
2026-07-23 23:28:18 -04:00
bruno d2953d98f9 fix: mobile toolbar height — icons no longer overflow
- .mobile-toolbar: 56px → 64px + padding 4px (was 0)
- .main-layout padding-bottom: 56px → 64px
- .mt-btn: height auto + min-height 48px (was fixed 48px)
- .mt-btn: gap 3px (was 2px), padding 4px (was 2px)
2026-07-23 23:21:32 -04:00
bruno 93d0bda627 feat: PDF support + Split View (P1 roadmap items)
#74 — Support PDF complet:
- backend/pdf_reader.py — pymupdf/pypdf text extraction
- .pdf added to SUPPORTED_EXTENSIONS in indexer.py
- PDF-aware file view API endpoint (metadata, text preview)
- Streaming endpoint /api/file/{vault}/pdf/stream
- Frontend PDF viewer with iframe, toolbar, download
- CSS for PDF viewer container

#75 — Split View (PaneManager):
- New module frontend/js/pane-manager.js — ES module
- 1-4 pane CSS grid with resize handles
- Split right/down via keyboard (Ctrl+Alt+\) or PaneManager API
- Persistence in localStorage (obsigate-panes)
- Collapse to single pane, per-pane active state

285 tests passent
2026-07-23 17:33:51 -04:00
bruno 5b956f8d95 Drop debounced search on input, search only on Enter
CI / lint (push) Failing after 25s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Failing after 13s
2026-07-21 10:14:26 -04:00
bruno 6a10051d78 Remove emoji prefixes from search and add tabs label
CI / lint (push) Failing after 29s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Failing after 22s
2026-07-21 09:47:41 -04:00
bruno c3c5f11e9b Move sidebar and offline imports to lazy loading
CI / lint (push) Failing after 21s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Failing after 10s
2026-07-20 22:31:07 -04:00
bruno 790f97e501 Replace hardcoded French strings with i18n calls
CI / lint (push) Failing after 1m28s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Failing after 17s
Initialize i18n before auth so t() works when rendering
auth-dependent UI, and build the command palette lazily so
translations are loaded first. Bump service worker cache version.
2026-07-20 20:16:34 -04:00
bruno cc22ffe6df fix: SW-killer script in index.html — auto-unregister stale Service Worker
CI / lint (push) Failing after 24s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Failing after 12s
The SW was the root cause of all persistent French text issues.
Even after rebuild, browsers with a registered SW would serve
cached old files (viewer.js without data-i18n, old locale JSONs).

SW-killer runs before any module script:
1. Detects if SW is controlling the page
2. Unregisters all SW registrations
3. Clears all caches
4. Reloads the page once (sessionStorage flag to prevent loop)

Other fixes in this commit:
- auth.js: import setLocale statically (was dynamic import)
- auth.js: import loadVaults/loadTags from sidebar.js
- sw.js: add JS modules + locales to STATIC_ASSETS for versioning
- sw.js: CACHE_VERSION v4→v5
2026-06-21 23:12:45 -04:00
bruno 72622f3dfb fix: SW cache bust — add JS modules + locales to STATIC_ASSETS
CI / lint (push) Failing after 24s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Failing after 11s
Root cause: cacheFirstStatic() in sw.js was caching viewer.js,
i18n.js, auth.js, dashboard.js, and locale JSON files under the old
CACHE_VERSION. Even after rebuild, the old SW served stale cached
files without data-i18n attributes, so dashboard stayed in French.

Changes:
- sw.js: add js/viewer.js, js/i18n.js, js/auth.js, js/dashboard.js,
  js/app.js, locales/en.json, locales/fr.json to STATIC_ASSETS
  so they are versioned with CACHE_VERSION and properly invalidated
- CACHE_VERSION already bumped to v5 in previous commit

Manual fix for existing clients:
  Chrome → F12 → Application → Service Workers → Unregister
  Or: chrome://serviceworker-internals/ → Unregister
  Then Ctrl+Shift+R to hard-refresh
2026-06-21 11:53:58 -04:00
bruno bea23820ab fix: Sign out + login flow + cache bust for i18n
CI / lint (push) Failing after 20s
CI / test (push) Has been skipped
CI / build (push) Has been skipped
CI / e2e (push) Has been skipped
CI / security (push) Failing after 11s
- auth.js: window.handleLogout at module top level (was inside
  renderUserMenu, not always called). Fixes settings dropdown
  'Sign out' onclick='handleLogout()' doing nothing.
- auth.js: add missing imports (loadVaults, loadTags from sidebar.js)
  and dynamic import for IndexUpdateManager (circular dep avoidance).
  Fixes 'loadVaults is not defined' error on login.
- sw.js: CACHE_VERSION v4→v5 to bust stale Service Worker cache
  that was serving old viewer.js without data-i18n attributes,
  causing dashboard tabs to stay French despite English profile.

To apply: rebuild container + unregister SW in DevTools + reload.
2026-06-21 11:37:51 -04:00