fix: split view — plus de panneaux vides, transfert auto de l'onglet
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
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
- _hasAnyTab(): empêche split si aucun onglet ouvert (tous les points d'entrée) - _copyActiveTabToNewPane(): copie l'onglet actif dans le nouveau panneau - Menu contextuel: l'onglet cliqué-droit est transféré dans le nouveau panneau - Raccourci clavier Ctrl+Alt+\: transfert l'onglet actif dans le nouveau panneau - Boutons split: vérifient _hasAnyTab() avant d'agir - Singleton ui.js: même comportement (split + transfert de l'onglet)
This commit is contained in:
+77
-10
@@ -69,11 +69,11 @@ function createPaneTabManager(paneId) {
|
||||
`;
|
||||
btns.querySelector('[data-action="split-right"]').addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (window.PaneManager) window.PaneManager.splitRight();
|
||||
if (window.PaneManager && window.PaneManager._hasAnyTab()) window.PaneManager.splitRight();
|
||||
});
|
||||
btns.querySelector('[data-action="split-down"]').addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (window.PaneManager) window.PaneManager.splitDown();
|
||||
if (window.PaneManager && window.PaneManager._hasAnyTab()) window.PaneManager.splitDown();
|
||||
});
|
||||
this._tabBar.appendChild(btns);
|
||||
if (typeof safeCreateIcons === 'function') safeCreateIcons();
|
||||
@@ -539,8 +539,23 @@ function createPaneTabManager(paneId) {
|
||||
menu.addEventListener('click', (e) => {
|
||||
const action = e.target.closest('.context-menu-item')?.dataset.action;
|
||||
if (action === 'moveTo') return; // handled by hover
|
||||
if (action === 'splitRight') { if (pm) { pm.splitRight(); menu.remove(); return; } }
|
||||
else if (action === 'splitDown') { if (pm) { pm.splitDown(); menu.remove(); return; } }
|
||||
if (action === 'splitRight') {
|
||||
if (pm && pm._hasAnyTab()) {
|
||||
pm.splitRight();
|
||||
// Transfer this specific tab to the new pane
|
||||
const newPaneId = pm.panes.length - 1;
|
||||
pm.transferTab(this.paneId, tabId, newPaneId);
|
||||
menu.remove(); return;
|
||||
}
|
||||
}
|
||||
else if (action === 'splitDown') {
|
||||
if (pm && pm._hasAnyTab()) {
|
||||
pm.splitDown();
|
||||
const newPaneId = pm.panes.length - 1;
|
||||
pm.transferTab(this.paneId, tabId, newPaneId);
|
||||
menu.remove(); return;
|
||||
}
|
||||
}
|
||||
else if (action === 'closePane') { if (pm) { pm.closeActivePane(); menu.remove(); return; } }
|
||||
else if (action === 'close') this.close(tabId);
|
||||
else if (action === 'closeOthers') this.closeOthers(tabId);
|
||||
@@ -660,20 +675,60 @@ const PaneManager = {
|
||||
// ------------------------------------------------------------------
|
||||
splitRight() {
|
||||
if (this.panes.length >= PANE_MAX) return;
|
||||
// Don't split if no tab is open anywhere
|
||||
if (!this._hasAnyTab()) return;
|
||||
this.layout = 'horizontal';
|
||||
if (this.panes.length === 0) this._buildGrid(2);
|
||||
else this._addPane();
|
||||
if (this.panes.length === 0) {
|
||||
this._buildGrid(2);
|
||||
// Copy active tab to the new pane
|
||||
this._copyActiveTabToNewPane();
|
||||
} else {
|
||||
this._addPane();
|
||||
}
|
||||
this._persist();
|
||||
},
|
||||
|
||||
splitDown() {
|
||||
if (this.panes.length >= PANE_MAX) return;
|
||||
if (!this._hasAnyTab()) return;
|
||||
this.layout = 'vertical';
|
||||
if (this.panes.length === 0) this._buildGrid(2);
|
||||
else this._addPane();
|
||||
if (this.panes.length === 0) {
|
||||
this._buildGrid(2);
|
||||
this._copyActiveTabToNewPane();
|
||||
} else {
|
||||
this._addPane();
|
||||
}
|
||||
this._persist();
|
||||
},
|
||||
|
||||
/** Check if any pane has at least one tab */
|
||||
_hasAnyTab() {
|
||||
if (!this.isSplit()) {
|
||||
// Check singleton in single-pane mode
|
||||
if (window._singletonTabManager && window._singletonTabManager._tabs.length > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
for (const tm of Object.values(this.tabManagers)) {
|
||||
if (tm._tabs && tm._tabs.length > 0) return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/** Copy the active tab to the newly created last pane */
|
||||
_copyActiveTabToNewPane() {
|
||||
const newPaneId = this.panes.length - 1;
|
||||
const srcTm = this.tabManagers[this.activePaneId];
|
||||
const dstTm = this.tabManagers[newPaneId];
|
||||
if (!srcTm || !dstTm || !srcTm._activeTabId) return;
|
||||
const cache = srcTm._tabCache[srcTm._activeTabId];
|
||||
if (cache) {
|
||||
setTimeout(() => {
|
||||
dstTm.open(cache.vault, cache.path);
|
||||
}, 150);
|
||||
}
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Close pane
|
||||
// ------------------------------------------------------------------
|
||||
@@ -1268,11 +1323,23 @@ if (typeof window !== 'undefined') {
|
||||
document.addEventListener('keydown', (e) => {
|
||||
if (e.ctrlKey && e.altKey && !e.shiftKey && e.key === '\\') {
|
||||
e.preventDefault();
|
||||
PaneManager.splitRight();
|
||||
if (PaneManager._hasAnyTab()) {
|
||||
PaneManager.splitRight();
|
||||
// Transfer active tab to new pane
|
||||
const tm = PaneManager.getActiveTabManager();
|
||||
if (tm && tm._activeTabId) {
|
||||
setTimeout(() => {
|
||||
const newPaneId = PaneManager.panes.length - 1;
|
||||
PaneManager.transferTab(PaneManager.activePaneId === newPaneId ? 0 : PaneManager.activePaneId, tm._activeTabId, newPaneId);
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e.ctrlKey && e.altKey && e.shiftKey && e.key === '\\') {
|
||||
e.preventDefault();
|
||||
PaneManager.splitDown();
|
||||
if (PaneManager._hasAnyTab()) {
|
||||
PaneManager.splitDown();
|
||||
}
|
||||
}
|
||||
// Close active pane
|
||||
if (e.ctrlKey && e.altKey && !e.shiftKey && (e.key === 'w' || e.key === 'W') && PaneManager.isSplit()) {
|
||||
|
||||
+16
-2
@@ -2351,8 +2351,22 @@ export const TabManager = {
|
||||
|
||||
menu.addEventListener("click", (e) => {
|
||||
const action = e.target.closest(".context-menu-item")?.dataset.action;
|
||||
if (action === "splitRight") { if (window.PaneManager) { window.PaneManager.splitRight(); menu.remove(); return; } }
|
||||
else if (action === "splitDown") { if (window.PaneManager) { window.PaneManager.splitDown(); menu.remove(); return; } }
|
||||
if (action === "splitRight") {
|
||||
if (window.PaneManager && window.PaneManager._hasAnyTab && window.PaneManager._hasAnyTab()) {
|
||||
window.PaneManager.splitRight();
|
||||
const newPaneId = window.PaneManager.panes.length - 1;
|
||||
window.PaneManager.transferTab(0, tabId, newPaneId);
|
||||
menu.remove(); return;
|
||||
}
|
||||
}
|
||||
else if (action === "splitDown") {
|
||||
if (window.PaneManager && window.PaneManager._hasAnyTab && window.PaneManager._hasAnyTab()) {
|
||||
window.PaneManager.splitDown();
|
||||
const newPaneId = window.PaneManager.panes.length - 1;
|
||||
window.PaneManager.transferTab(0, tabId, newPaneId);
|
||||
menu.remove(); return;
|
||||
}
|
||||
}
|
||||
else if (action === "closePane") { if (window.PaneManager) { window.PaneManager.closeActivePane(); menu.remove(); return; } }
|
||||
else if (action === "close") this.close(tabId);
|
||||
else if (action === "closeOthers") this.closeOthers(tabId);
|
||||
|
||||
Reference in New Issue
Block a user