feat: Ajout du redimensionnement manuel du panneau de notes

- Poignée de redimensionnement avec indicateur visuel permanent (3 points)
- Largeur ajustable entre 280px et 600px
- Sauvegarde automatique de la largeur préférée
- Optimisations avec requestAnimationFrame pour la fluidité
- Overlay pendant le drag pour capturer tous les mouvements
- Indicateur change de couleur au survol (gris → violet)
This commit is contained in:
Pierre Marx
2025-09-04 16:22:09 -04:00
parent 29a4cfb410
commit d66af7d99d
4 changed files with 218 additions and 2 deletions

View File

@@ -11,6 +11,11 @@ let callStats = {
appointments: 0
};
// Variables pour le redimensionnement des notes
let isResizingNotes = false;
let notesStartWidth = 380;
let notesStartX = 0;
// === GESTION DE LA CONNEXION ===
document.addEventListener('DOMContentLoaded', async () => {
// Initialiser l'indicateur SignalR
@@ -90,6 +95,9 @@ document.addEventListener('DOMContentLoaded', async () => {
// Charger les préférences utilisateur
loadUserPreferences();
// Initialiser le redimensionnement des notes
initNotesResize();
// Gérer les boutons de la modal de déconnexion (si on est sur la page principale)
const cancelLogoutBtn = document.getElementById('cancelLogoutBtn');
@@ -860,6 +868,16 @@ function showNotes() {
const toggleBtn = document.getElementById('toggleNotesBtn');
const webviewContainer = document.getElementById('webviewContainer');
// Restaurer la largeur sauvegardée
const savedWidth = localStorage.getItem('notesWidth');
if (savedWidth && notesSection) {
const width = parseInt(savedWidth);
if (width >= 280 && width <= 600) {
notesSection.style.width = `${width}px`;
document.documentElement.style.setProperty('--notes-width', `${width}px`);
}
}
notesSection.classList.add('visible');
toggleBtn.classList.add('active');
@@ -915,6 +933,19 @@ function loadUserPreferences() {
// L'utilisateur devra cliquer pour les afficher
}
// Charger la largeur sauvegardée des notes
const savedNotesWidth = localStorage.getItem('notesWidth');
if (savedNotesWidth) {
const width = parseInt(savedNotesWidth);
if (width >= 280 && width <= 600) {
document.documentElement.style.setProperty('--notes-width', `${width}px`);
const notesSection = document.getElementById('notesSection');
if (notesSection) {
notesSection.style.width = `${width}px`;
}
}
}
// Charger d'autres préférences si nécessaire
const lastTheme = localStorage.getItem('theme');
if (lastTheme) {
@@ -924,8 +955,10 @@ function loadUserPreferences() {
function saveUserPreferences() {
// Cette fonction peut être étendue pour sauvegarder d'autres préférences
const notesSection = document.getElementById('notesSection');
const preferences = {
notesVisible: document.getElementById('notesSection').classList.contains('visible'),
notesVisible: notesSection.classList.contains('visible'),
notesWidth: notesSection ? notesSection.offsetWidth : 380,
theme: document.body.getAttribute('data-theme') || 'light'
};
@@ -934,6 +967,99 @@ function saveUserPreferences() {
});
}
// === GESTION DU REDIMENSIONNEMENT DES NOTES ===
function initNotesResize() {
const resizeHandle = document.getElementById('notesResizeHandle');
const notesSection = document.getElementById('notesSection');
const webviewContainer = document.getElementById('webviewContainer');
if (!resizeHandle || !notesSection) return;
let rafId = null;
resizeHandle.addEventListener('mousedown', (e) => {
isResizingNotes = true;
notesStartX = e.clientX;
notesStartWidth = notesSection.offsetWidth;
// Ajouter les classes pour désactiver les transitions
notesSection.classList.add('resizing');
if (webviewContainer) {
webviewContainer.classList.add('resizing');
}
// Empêcher la sélection de texte pendant le redimensionnement
document.body.style.userSelect = 'none';
document.body.style.cursor = 'col-resize';
// Ajouter un overlay pour capturer tous les mouvements de souris
const overlay = document.createElement('div');
overlay.id = 'resize-overlay';
overlay.style.cssText = 'position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 9999; cursor: col-resize;';
document.body.appendChild(overlay);
e.preventDefault();
});
const handleMouseMove = (e) => {
if (!isResizingNotes) return;
// Utiliser requestAnimationFrame pour la fluidité
if (rafId) cancelAnimationFrame(rafId);
rafId = requestAnimationFrame(() => {
// Calculer la nouvelle largeur (inversé car le panneau est à droite)
const deltaX = notesStartX - e.clientX;
const newWidth = notesStartWidth + deltaX;
// Appliquer les limites min/max
const clampedWidth = Math.min(Math.max(newWidth, 280), 600);
// Mettre à jour la largeur avec transform pour plus de fluidité
notesSection.style.width = `${clampedWidth}px`;
// Mettre à jour la variable CSS pour la webview
document.documentElement.style.setProperty('--notes-width', `${clampedWidth}px`);
});
};
const handleMouseUp = () => {
if (!isResizingNotes) return;
isResizingNotes = false;
// Annuler l'animation frame en cours
if (rafId) cancelAnimationFrame(rafId);
// Retirer l'overlay
const overlay = document.getElementById('resize-overlay');
if (overlay) overlay.remove();
// Retirer les classes de redimensionnement
const notesSection = document.getElementById('notesSection');
const webviewContainer = document.getElementById('webviewContainer');
if (notesSection) {
notesSection.classList.remove('resizing');
}
if (webviewContainer) {
webviewContainer.classList.remove('resizing');
}
// Réactiver la sélection de texte
document.body.style.userSelect = '';
document.body.style.cursor = '';
// Sauvegarder la nouvelle largeur
if (notesSection) {
localStorage.setItem('notesWidth', notesSection.offsetWidth);
}
};
document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mouseup', handleMouseUp);
}
// === FONCTION DE RAFRAÎCHISSEMENT ===
function refreshCurrentWebview() {
if (activeCenter && webviews[activeCenter]) {