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)
This commit is contained in:
2026-07-27 21:06:47 -04:00
parent 0cea78b3b1
commit b27b38d32b
5 changed files with 555 additions and 57 deletions
+17 -9
View File
@@ -11,6 +11,14 @@ import { DashboardStatsWidget, DashboardRecentWidget, DashboardBookmarkWidget, D
import { openShareDialog } from './config.js';
import { cacheViewedFile, getCachedFile } from './offline.js';
import { t } from './i18n.js';
// Pane-aware content area helper
function getContentArea() {
if (window.PaneManager && window.PaneManager.isSplit()) {
return window.PaneManager.getActiveContentArea();
}
return document.getElementById('content-area');
}
// ---------------------------------------------------------------------------
// Outline/TOC Manager
// ---------------------------------------------------------------------------
@@ -135,7 +143,7 @@ const OutlineManager = {
const heading = document.getElementById(headingId);
if (!heading) return;
const contentArea = document.getElementById("content-area");
const contentArea = getContentArea();
if (!contentArea) return;
// Calculate offset for fixed header (if any)
@@ -209,7 +217,7 @@ const ScrollSpyManager = {
if (!headings || headings.length === 0) return;
const contentArea = document.getElementById("content-area");
const contentArea = getContentArea();
if (!contentArea) return;
const options = {
@@ -263,7 +271,7 @@ const ReadingProgressManager = {
init() {
this.destroy();
const contentArea = document.getElementById("content-area");
const contentArea = getContentArea();
if (!contentArea) return;
this.scrollHandler = this.throttle(() => {
@@ -275,7 +283,7 @@ const ReadingProgressManager = {
},
updateProgress() {
const contentArea = document.getElementById("content-area");
const contentArea = getContentArea();
const progressFill = document.getElementById("reading-progress-fill");
const progressText = document.getElementById("reading-progress-text");
@@ -304,7 +312,7 @@ const ReadingProgressManager = {
},
destroy() {
const contentArea = document.getElementById("content-area");
const contentArea = getContentArea();
if (contentArea && this.scrollHandler) {
contentArea.removeEventListener("scroll", this.scrollHandler);
}
@@ -332,7 +340,7 @@ export async function openFile(vaultName, filePath) {
syncActiveFileTreeItem(vaultName, filePath);
// Show loading state while fetching
const area = document.getElementById("content-area");
const area = getContentArea();
area.innerHTML = '<div class="loading-indicator"><div class="loading-spinner"></div><div>Chargement...</div></div>';
try {
@@ -400,7 +408,7 @@ async function renderBacklinksPanel(vault, path, container) {
}
export function renderFile(data) {
const area = document.getElementById("content-area");
const area = getContentArea();
// Handle PDF files — render in iframe with TOC sidebar
if (data.is_pdf) {
@@ -1051,7 +1059,7 @@ export function showWelcome() {
hideProgressBar();
// Restore or rebuild the dashboard with tabbed sections
const area = document.getElementById("content-area");
const area = getContentArea();
const home = document.getElementById("dashboard-home");
if (area && !home) {
@@ -1244,7 +1252,7 @@ export async function loadSavedSearches() {
}
export function showLoading() {
const area = document.getElementById("content-area");
const area = getContentArea();
area.innerHTML = `
<div class="loading-indicator">
<div class="loading-spinner"></div>