fix(dragdrop): amélioration sélection répertoire cible, déplacement arborescence et ouverture auto IA (#89)
This commit is contained in:
Vendored
+30
-15
@@ -13,6 +13,7 @@ import { t } from './i18n.js';
|
||||
import { showToast } from './ui.js';
|
||||
import { refreshSidebarTreePreservingState } from './sidebar.js';
|
||||
import { readDataTransferEntries, handleVaultDropUpload } from './upload.js';
|
||||
import booksLM from './bookslm.js';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// State
|
||||
@@ -52,15 +53,14 @@ function getDropTarget(el) {
|
||||
// Directory tree item
|
||||
const dirItem = closest('.tree-item[data-path]', el);
|
||||
if (dirItem) {
|
||||
// Only directories are valid targets
|
||||
const icon = dirItem.querySelector('[data-lucide]');
|
||||
const isDir = icon && (icon.getAttribute('data-lucide') === 'folder'
|
||||
|| icon.getAttribute('data-lucide') === 'chevron-right'
|
||||
|| icon.getAttribute('data-lucide') === 'chevron-down');
|
||||
// Heuristic: if the tree item has a child container sibling, it's a directory
|
||||
const isExplicitDir = dirItem.dataset.type === 'directory';
|
||||
const icon = dirItem.querySelector('[data-lucide], i');
|
||||
const iconName = icon?.getAttribute('data-lucide');
|
||||
const isFolderIcon = iconName === 'folder' || iconName === 'chevron-right' || iconName === 'chevron-down';
|
||||
const hasChildren = dirItem.nextElementSibling
|
||||
&& dirItem.nextElementSibling.classList.contains('tree-children');
|
||||
if (isDir || hasChildren) {
|
||||
|
||||
if (isExplicitDir || isFolderIcon || hasChildren) {
|
||||
return {
|
||||
vault: dirItem.dataset.vault,
|
||||
targetDir: dirItem.dataset.path,
|
||||
@@ -149,9 +149,10 @@ function onDragStart(e) {
|
||||
if (!vault || path === undefined) return;
|
||||
|
||||
// Determine type: directory or file
|
||||
const isExplicitDir = treeItem.dataset.type === 'directory';
|
||||
const hasChildren = treeItem.nextElementSibling
|
||||
&& treeItem.nextElementSibling.classList.contains('tree-children');
|
||||
const type = hasChildren ? 'directory' : 'file';
|
||||
const type = (isExplicitDir || hasChildren) ? 'directory' : 'file';
|
||||
|
||||
dragState = { vault, path, type, element: treeItem };
|
||||
|
||||
@@ -159,6 +160,9 @@ function onDragStart(e) {
|
||||
e.dataTransfer.effectAllowed = 'move';
|
||||
// Prefix with 'tree:' so pane drop zones can distinguish from tab drags
|
||||
e.dataTransfer.setData('text/plain', 'tree:' + JSON.stringify({ vault, path }));
|
||||
e.dataTransfer.setData('tree:vault', vault);
|
||||
e.dataTransfer.setData('tree:path', path);
|
||||
e.dataTransfer.setData('tree:type', type);
|
||||
|
||||
// Visual: reduce opacity of source
|
||||
treeItem.classList.add(DRAG_SOURCE_CLASS);
|
||||
@@ -170,10 +174,12 @@ function onDragStart(e) {
|
||||
if (item.classList.contains('vault-item')) {
|
||||
item.classList.add(DRAG_VALID_TARGET_CLASS);
|
||||
} else {
|
||||
const icon = item.querySelector('[data-lucide]');
|
||||
const icon = item.querySelector('[data-lucide], i');
|
||||
const iconName = icon?.getAttribute('data-lucide');
|
||||
const isFolder = item.dataset.type === 'directory' || iconName === 'folder' || iconName === 'chevron-right' || iconName === 'chevron-down';
|
||||
const hasChildContainer = item.nextElementSibling
|
||||
&& item.nextElementSibling.classList.contains('tree-children');
|
||||
if (icon && (icon.getAttribute('data-lucide') === 'folder' || hasChildContainer)) {
|
||||
if (isFolder || hasChildContainer) {
|
||||
item.classList.add(DRAG_VALID_TARGET_CLASS);
|
||||
}
|
||||
}
|
||||
@@ -436,16 +442,25 @@ export function initGlobalDropOverlay() {
|
||||
if (zoneType === 'vault') {
|
||||
const activeVault = window.state?.activeVault || (document.querySelector('.tree-item.vault-item')?.dataset?.vault);
|
||||
if (activeVault) {
|
||||
await handleVaultDropUpload(activeVault, '', items);
|
||||
// Pass null for targetDir so user is prompted to choose destination folder
|
||||
await handleVaultDropUpload(activeVault, null, items);
|
||||
} else {
|
||||
showToast('Aucun vault sélectionné', 'error');
|
||||
}
|
||||
} else if (zoneType === 'ai') {
|
||||
// Dispatch or pass to BooksLM assistant
|
||||
if (window.BooksLMInstance) {
|
||||
window.BooksLMInstance.handleExternalDroppedItems(items);
|
||||
// Automatically open assistant if not already open and pass items
|
||||
if (booksLM) {
|
||||
if (!booksLM._isOpen) {
|
||||
await booksLM.openForCurrentContext();
|
||||
}
|
||||
await booksLM.handleExternalDroppedItems(items);
|
||||
} else if (window.BooksLMInstance) {
|
||||
if (!window.BooksLMInstance._isOpen) {
|
||||
await window.BooksLMInstance.openForCurrentContext();
|
||||
}
|
||||
await window.BooksLMInstance.handleExternalDroppedItems(items);
|
||||
} else {
|
||||
showToast("Assistant IA non initialisé", 'warning');
|
||||
showToast("Assistant IA non disponible", 'warning');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user