Des tonnes de modifications notamment VIM / Couleurs / typos

This commit is contained in:
2025-11-11 15:41:51 +01:00
parent 439880b08f
commit 6face7a02f
59 changed files with 7857 additions and 960 deletions

View File

@ -20,6 +20,11 @@ class FileTree {
// Event listener délégué pour les clics sur les folder-headers
sidebar.addEventListener('click', (e) => {
// Ignorer les clics sur les checkboxes
if (e.target.classList.contains('selection-checkbox')) {
return;
}
// Vérifier d'abord si c'est un folder-header ou un de ses enfants
const folderHeader = e.target.closest('.folder-header');
if (folderHeader && !e.target.closest('.file-item')) {
@ -489,4 +494,234 @@ document.addEventListener('keydown', (event) => {
*/
document.addEventListener('DOMContentLoaded', () => {
window.fileTree = new FileTree();
});
window.selectionManager = new SelectionManager();
});
/**
* SelectionManager - Gère le mode sélection et la suppression en masse
*/
class SelectionManager {
constructor() {
this.isSelectionMode = false;
this.selectedPaths = new Set();
this.init();
}
init() {
// Écouter les événements HTMX pour réinitialiser les listeners après les swaps
document.body.addEventListener('htmx:afterSwap', (event) => {
if (event.detail.target.id === 'file-tree' || event.detail.target.closest('#file-tree')) {
this.attachCheckboxListeners();
if (this.isSelectionMode) {
this.showCheckboxes();
}
}
});
document.body.addEventListener('htmx:oobAfterSwap', (event) => {
if (event.detail.target.id === 'file-tree') {
this.attachCheckboxListeners();
if (this.isSelectionMode) {
this.showCheckboxes();
}
}
});
// Attacher les listeners initiaux
setTimeout(() => this.attachCheckboxListeners(), 500);
}
attachCheckboxListeners() {
const checkboxes = document.querySelectorAll('.selection-checkbox');
checkboxes.forEach(checkbox => {
// Retirer l'ancien listener s'il existe
checkbox.removeEventListener('change', this.handleCheckboxChange);
// Ajouter le nouveau listener
checkbox.addEventListener('change', (e) => this.handleCheckboxChange(e));
});
}
handleCheckboxChange(e) {
const checkbox = e.target;
const path = checkbox.dataset.path;
if (checkbox.checked) {
window.selectionManager.selectedPaths.add(path);
} else {
window.selectionManager.selectedPaths.delete(path);
}
window.selectionManager.updateToolbar();
}
toggleSelectionMode() {
this.isSelectionMode = !this.isSelectionMode;
if (this.isSelectionMode) {
this.showCheckboxes();
document.getElementById('toggle-selection-mode')?.classList.add('active');
} else {
this.hideCheckboxes();
this.clearSelection();
document.getElementById('toggle-selection-mode')?.classList.remove('active');
}
}
showCheckboxes() {
const checkboxes = document.querySelectorAll('.selection-checkbox');
checkboxes.forEach(checkbox => {
checkbox.style.display = 'inline-block';
});
}
hideCheckboxes() {
const checkboxes = document.querySelectorAll('.selection-checkbox');
checkboxes.forEach(checkbox => {
checkbox.style.display = 'none';
checkbox.checked = false;
});
}
clearSelection() {
this.selectedPaths.clear();
this.updateToolbar();
}
updateToolbar() {
const toolbar = document.getElementById('selection-toolbar');
const countSpan = document.getElementById('selection-count');
if (this.selectedPaths.size > 0) {
toolbar.style.display = 'flex';
countSpan.textContent = `${this.selectedPaths.size} élément(s) sélectionné(s)`;
} else {
toolbar.style.display = 'none';
}
}
showDeleteConfirmationModal() {
const modal = document.getElementById('delete-confirmation-modal');
const countSpan = document.getElementById('delete-count');
const itemsList = document.getElementById('delete-items-list');
countSpan.textContent = this.selectedPaths.size;
// Générer la liste des éléments à supprimer
itemsList.innerHTML = '';
const ul = document.createElement('ul');
ul.style.margin = '0';
ul.style.padding = '0 0 0 1.5rem';
ul.style.color = 'var(--text-primary)';
this.selectedPaths.forEach(path => {
const li = document.createElement('li');
li.style.marginBottom = '0.5rem';
// Déterminer si c'est un dossier
const checkbox = document.querySelector(`.selection-checkbox[data-path="${path}"]`);
const isDir = checkbox?.dataset.isDir === 'true';
li.innerHTML = `${isDir ? '📁' : '📄'} <code>${path}</code>`;
ul.appendChild(li);
});
itemsList.appendChild(ul);
modal.style.display = 'flex';
}
hideDeleteConfirmationModal() {
const modal = document.getElementById('delete-confirmation-modal');
modal.style.display = 'none';
}
async deleteSelectedItems() {
const paths = Array.from(this.selectedPaths);
if (paths.length === 0) {
alert('Aucun élément sélectionné');
return;
}
try {
// Construire le corps de la requête au format query string
// Le backend attend: paths[]=path1&paths[]=path2
const params = new URLSearchParams();
paths.forEach(path => {
params.append('paths[]', path);
});
// Utiliser fetch() avec le corps en query string
const response = await fetch('/api/files/delete-multiple', {
method: 'DELETE',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: params.toString()
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const html = await response.text();
// Parser le HTML pour trouver les éléments avec hx-swap-oob
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
// Traiter les swaps out-of-band manuellement
doc.querySelectorAll('[hx-swap-oob]').forEach(element => {
const targetId = element.id;
const target = document.getElementById(targetId);
if (target) {
target.innerHTML = element.innerHTML;
// Déclencher l'événement htmx pour que les listeners se réattachent
htmx.process(target);
}
});
console.log(`${paths.length} élément(s) supprimé(s)`);
// Fermer la modale
this.hideDeleteConfirmationModal();
// Réinitialiser la sélection et garder le mode sélection actif
this.clearSelection();
// Réattacher les listeners sur les nouvelles checkboxes
setTimeout(() => {
this.attachCheckboxListeners();
if (this.isSelectionMode) {
this.showCheckboxes();
}
}, 100);
} catch (error) {
console.error('Erreur lors de la suppression:', error);
alert('Erreur lors de la suppression des éléments: ' + error.message);
}
}
}
/**
* Fonctions globales pour les boutons
*/
window.toggleSelectionMode = function() {
window.selectionManager.toggleSelectionMode();
};
window.deleteSelected = function() {
window.selectionManager.showDeleteConfirmationModal();
};
window.cancelSelection = function() {
window.selectionManager.toggleSelectionMode();
};
window.hideDeleteConfirmationModal = function() {
window.selectionManager.hideDeleteConfirmationModal();
};
window.confirmDelete = function() {
window.selectionManager.deleteSelectedItems();
};