refactor(js): move multiSelect into batchToolbar + move residual method into relevant components
This commit is contained in:
+1
-1
@@ -25,7 +25,7 @@
|
||||
@import url("./components/notifications.css");
|
||||
@import url("./components/userMenu.css");
|
||||
@import url("./components/languageSelector.css");
|
||||
@import url("./components/multiSelect.css");
|
||||
@import url("./components/batchToolbar.css");
|
||||
@import url("./components/spinner.css");
|
||||
@import url("./components/search.css");
|
||||
@import url("./components/icons.css");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { i18n } from '../core/i18n.js';
|
||||
import { inlineViewer } from '../features/files/inlineViewer.js';
|
||||
import { multiSelect } from '../features/files/multiSelect.js';
|
||||
import { batchToolbar } from '../features/files/batchToolbar.js';
|
||||
import { resolveHomeFolder } from './authSession.js';
|
||||
import { updateHistory } from './main.js';
|
||||
import { app } from './state.js';
|
||||
@@ -217,9 +217,9 @@ async function loadFiles(options = { insertHistory: true }) {
|
||||
|
||||
ui._items.clear();
|
||||
ui.resetFilesList();
|
||||
if (multiSelect) {
|
||||
multiSelect.clear();
|
||||
multiSelect.init(); // this will wire buttons & select-all-checkbox
|
||||
if (batchToolbar) {
|
||||
batchToolbar.clear();
|
||||
batchToolbar.init(); // this will wire buttons & select-all-checkbox
|
||||
}
|
||||
|
||||
/** @type {FolderItem[]} */
|
||||
|
||||
@@ -12,7 +12,7 @@ import { formatFileSize, formatQuotaSize } from '../core/formatters.js';
|
||||
import { i18n } from '../core/i18n.js';
|
||||
import { oxiIconsInit } from '../core/icons.js';
|
||||
import { fileOps } from '../features/files/fileOperations.js';
|
||||
import { multiSelect } from '../features/files/multiSelect.js';
|
||||
import { batchToolbar } from '../features/files/batchToolbar.js';
|
||||
import { favorites } from '../features/library/favorites.js';
|
||||
import { recent } from '../features/library/recent.js';
|
||||
import { fileSharing } from '../features/sharing/fileSharing.js';
|
||||
@@ -50,7 +50,7 @@ let uploadDropdownDocumentClickHandler = null;
|
||||
let uploadDropdownBindingsController = null;
|
||||
let actionsBarDelegationBound = false;
|
||||
|
||||
const _multiSelectButons = `
|
||||
const _batchToolbarButons = `
|
||||
<div class="action-buttons batch-selection-bar hidden" id="multi-select-buttons">
|
||||
<div class="list-header-checkbox">
|
||||
<button class="batch-bar-close" id="batch-selection-close" title="Cancel selection">
|
||||
@@ -117,7 +117,7 @@ const ACTIONS_BAR_TEMPLATES = {
|
||||
<span data-i18n="actions.new_folder">New folder</span>
|
||||
</button>
|
||||
</div>
|
||||
${_multiSelectButons}
|
||||
${_batchToolbarButons}
|
||||
${_toggleButtons}
|
||||
`,
|
||||
trash: `
|
||||
@@ -131,7 +131,7 @@ const ACTIONS_BAR_TEMPLATES = {
|
||||
`,
|
||||
favorites: `
|
||||
<div class="action-buttons" id="default-buttons"></div>
|
||||
${_multiSelectButons}
|
||||
${_batchToolbarButons}
|
||||
${_toggleButtons}
|
||||
`,
|
||||
recent: `
|
||||
@@ -141,7 +141,7 @@ const ACTIONS_BAR_TEMPLATES = {
|
||||
<span data-i18n="actions.clear_recent">Clear recent</span>
|
||||
</button>
|
||||
</div>
|
||||
${_multiSelectButons}
|
||||
${_batchToolbarButons}
|
||||
${_toggleButtons}
|
||||
`,
|
||||
sharedwithme: `
|
||||
@@ -386,9 +386,9 @@ function initApp() {
|
||||
}
|
||||
|
||||
// Initialize multi-select / batch actions
|
||||
if (multiSelect?.init) {
|
||||
if (batchToolbar?.init) {
|
||||
console.log('Initializing multi-select module');
|
||||
multiSelect.init();
|
||||
batchToolbar.init();
|
||||
}
|
||||
|
||||
window.addEventListener('authenticationDone', async () => {
|
||||
|
||||
+10
-10
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
import { i18n } from '../core/i18n.js';
|
||||
import { multiSelect } from '../features/files/multiSelect.js';
|
||||
import { batchToolbar } from '../features/files/batchToolbar.js';
|
||||
import { favorites } from '../features/library/favorites.js';
|
||||
import { musicView } from '../features/library/music.js';
|
||||
import { photosView } from '../features/library/photos.js';
|
||||
@@ -201,7 +201,7 @@ function switchToSharedSection() {
|
||||
sharedView.show();
|
||||
});
|
||||
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
}
|
||||
|
||||
function switchToSharedWithMeSection() {
|
||||
@@ -221,7 +221,7 @@ function switchToSharedWithMeSection() {
|
||||
toggleFileContainer(true);
|
||||
syncViewContainers();
|
||||
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
|
||||
// Load and render items into the files container
|
||||
sharedWithMeView.init();
|
||||
@@ -253,7 +253,7 @@ function switchToFilesSection() {
|
||||
app.currentPath = app.userHomeFolderId || '';
|
||||
app.breadcrumbPath = [];
|
||||
ui.updateBreadcrumb();
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
|
||||
// temp solution
|
||||
sharedView.loadItems().then(() => {
|
||||
@@ -296,7 +296,7 @@ function switchToFavoritesSection() {
|
||||
`);
|
||||
}
|
||||
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
}
|
||||
|
||||
function switchToRecentFilesSection() {
|
||||
@@ -329,7 +329,7 @@ function switchToRecentFilesSection() {
|
||||
<p>Error loading the recent module</p>
|
||||
`);
|
||||
}
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
}
|
||||
|
||||
function switchToPhotosSection() {
|
||||
@@ -352,7 +352,7 @@ function switchToPhotosSection() {
|
||||
if (photosView) {
|
||||
photosView.show();
|
||||
}
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
}
|
||||
|
||||
function switchToTrashSection() {
|
||||
@@ -377,7 +377,7 @@ function switchToTrashSection() {
|
||||
// Load trash items
|
||||
loadTrashItems();
|
||||
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
}
|
||||
|
||||
function switchToMusicSection() {
|
||||
@@ -404,7 +404,7 @@ function switchToMusicSection() {
|
||||
if (musicView) {
|
||||
musicView.show();
|
||||
}
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,7 +423,7 @@ function activateFilesUI() {
|
||||
breadcrumb?.classList.remove('hidden');
|
||||
toggleFileContainer(true);
|
||||
syncViewContainers();
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { escapeHtml, formatDateTime } from '../core/formatters.js';
|
||||
import { i18n } from '../core/i18n.js';
|
||||
import { fileOps } from '../features/files/fileOperations.js';
|
||||
import { multiSelect } from '../features/files/multiSelect.js';
|
||||
import { batchToolbar } from '../features/files/batchToolbar.js';
|
||||
import * as pathTooltip from '../features/pathTooltip.js';
|
||||
import { appElements } from './state.js';
|
||||
import { ui } from './ui.js';
|
||||
@@ -22,7 +22,7 @@ async function loadTrashItems() {
|
||||
const elements = appElements;
|
||||
|
||||
try {
|
||||
if (multiSelect) multiSelect.clear();
|
||||
if (batchToolbar) batchToolbar.clear();
|
||||
pathTooltip.destroy(elements.filesList);
|
||||
ui.resetFilesList(); // ensure also list visible & error hidden
|
||||
elements.filesList.innerHTML = `
|
||||
|
||||
+18
-18
@@ -13,7 +13,7 @@ import { OxiIcons } from '../core/icons.js';
|
||||
import { contextMenus } from '../features/files/contextMenus.js';
|
||||
import { fileOps } from '../features/files/fileOperations.js';
|
||||
import { inlineViewer } from '../features/files/inlineViewer.js';
|
||||
import { multiSelect } from '../features/files/multiSelect.js';
|
||||
import { batchToolbar } from '../features/files/batchToolbar.js';
|
||||
import { wopiEditor } from '../features/files/wopiEditor.js';
|
||||
import { favorites } from '../features/library/favorites.js';
|
||||
import { recent } from '../features/library/recent.js';
|
||||
@@ -727,9 +727,9 @@ const ui = {
|
||||
* @param {any} dataTransfer fallback if nothing is selected
|
||||
*/
|
||||
async _dropToFolder(action, targetFolderId, dataTransfer) {
|
||||
const selection = multiSelect.getSelection(targetFolderId);
|
||||
const selection = batchToolbar.getSelection(targetFolderId);
|
||||
|
||||
multiSelect.clear();
|
||||
batchToolbar.clear();
|
||||
|
||||
if (selection.fileIds.length === 0 && selection.folderIds.length === 0) {
|
||||
// try to use dataTransfer (direct move without selection)
|
||||
@@ -774,7 +774,7 @@ const ui = {
|
||||
console.error(`drag and drop: action ${action} unknown`);
|
||||
return;
|
||||
}
|
||||
multiSelect.showBatchResult(action, result);
|
||||
batchToolbar.showBatchResult(action, result);
|
||||
console.log(result);
|
||||
},
|
||||
|
||||
@@ -941,8 +941,8 @@ const ui = {
|
||||
}
|
||||
|
||||
// shiftkey is used to complete selection
|
||||
if (e.shiftKey && multiSelect) {
|
||||
multiSelect.handleToggleItem(card, e);
|
||||
if (e.shiftKey && batchToolbar) {
|
||||
batchToolbar.handleToggleItem(card, e);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1512,13 +1512,13 @@ const ui = {
|
||||
|
||||
/**
|
||||
* Toggle selection state of a file/folder card.
|
||||
* Routes through the multiSelect module so batch actions know about selected items.
|
||||
* Routes through the batchToolbar module so batch actions know about selected items.
|
||||
* @param {HTMLDivElement} card
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
function toggleCardSelection(card, event) {
|
||||
if (multiSelect) {
|
||||
multiSelect.handleToggleItem(card, event);
|
||||
if (batchToolbar) {
|
||||
batchToolbar.handleToggleItem(card, event);
|
||||
} else {
|
||||
card.classList.toggle('selected');
|
||||
}
|
||||
@@ -1641,17 +1641,17 @@ function initRubberBandSelection() {
|
||||
if (intersects) {
|
||||
card.classList.add('selected');
|
||||
|
||||
// Sync with multiSelect module
|
||||
if (multiSelect) {
|
||||
const info = multiSelect._extractInfo(/** @type {HTMLDivElement} */ (card));
|
||||
if (info) multiSelect.select(info.id, info.name, info.type, info.parentId);
|
||||
// Sync with batchToolbar module
|
||||
if (batchToolbar) {
|
||||
const info = batchToolbar._extractInfo(/** @type {HTMLDivElement} */ (card));
|
||||
if (info) batchToolbar.select(info.id, info.name, info.type, info.parentId);
|
||||
}
|
||||
} else {
|
||||
card.classList.remove('selected');
|
||||
// Deselect from multiSelect module
|
||||
if (multiSelect) {
|
||||
const info = multiSelect._extractInfo(/** @type {HTMLDivElement} */ (card));
|
||||
if (info) multiSelect.deselect(info.id);
|
||||
// Deselect from batchToolbar module
|
||||
if (batchToolbar) {
|
||||
const info = batchToolbar._extractInfo(/** @type {HTMLDivElement} */ (card));
|
||||
if (info) batchToolbar.deselect(info.id);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1663,7 +1663,7 @@ function initRubberBandSelection() {
|
||||
const hadSelection = selRect.style.display === 'block';
|
||||
selRect.style.display = 'none';
|
||||
// Update the batch bar after rubber band selection completes
|
||||
if (multiSelect) multiSelect._syncUI();
|
||||
if (batchToolbar) batchToolbar._syncUI();
|
||||
// Suppress the click event that follows mouseup so the global
|
||||
// deselect handler doesn't immediately clear the selection.
|
||||
if (hadSelection) {
|
||||
|
||||
@@ -86,6 +86,9 @@ export class ResourceListComponent {
|
||||
/** @type {Set<string>} */
|
||||
this._selected = new Set();
|
||||
|
||||
/** Index of the last clicked item — used for shift-click range selection. */
|
||||
this._lastClickedIndex = -1;
|
||||
|
||||
this._ownerVisible = this._cfg.showOwner;
|
||||
|
||||
this._initDelegation();
|
||||
@@ -110,8 +113,10 @@ export class ResourceListComponent {
|
||||
|
||||
this._selected.clear();
|
||||
this._items.clear();
|
||||
this._lastClickedIndex = -1;
|
||||
|
||||
this._appendItems(folders, files, groupFn);
|
||||
this._wireSelectAll();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,6 +137,40 @@ export class ResourceListComponent {
|
||||
if (header) this._container.appendChild(header);
|
||||
this._selected.clear();
|
||||
this._items.clear();
|
||||
this._lastClickedIndex = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect all items without removing them from the DOM.
|
||||
* Used by the batch toolbar after an operation completes.
|
||||
*/
|
||||
clearSelection() {
|
||||
this._selected.clear();
|
||||
this._lastClickedIndex = -1;
|
||||
this._container.querySelectorAll('.file-item.selected').forEach((card) => {
|
||||
card.classList.remove('selected');
|
||||
const cb = /** @type {HTMLInputElement | null} */ (card.querySelector('.item-checkbox'));
|
||||
if (cb) cb.checked = false;
|
||||
});
|
||||
this._syncSelectAllCheckbox();
|
||||
this._cfg.onSelectionChange?.([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Select all visible items in the container.
|
||||
*/
|
||||
selectAll() {
|
||||
this._container.querySelectorAll('.file-item').forEach((card) => {
|
||||
const el = /** @type {HTMLElement} */ (card);
|
||||
const id = el.dataset.fileId || el.dataset.folderId || '';
|
||||
if (!id) return;
|
||||
el.classList.add('selected');
|
||||
const cb = /** @type {HTMLInputElement | null} */ (el.querySelector('.item-checkbox'));
|
||||
if (cb) cb.checked = true;
|
||||
this._selected.add(id);
|
||||
});
|
||||
this._syncSelectAllCheckbox();
|
||||
this._notifySelectionChange();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -406,9 +445,13 @@ export class ResourceListComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
// Checkbox cell → selection
|
||||
// Checkbox cell → selection (shift extends range)
|
||||
if (cfg.selectable && target.closest('.checkbox-cell')) {
|
||||
this._toggleSelection(card, /** @type {MouseEvent} */ (e));
|
||||
if (e.shiftKey) {
|
||||
this._handleShiftSelect(card);
|
||||
} else {
|
||||
this._toggleSelection(card);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -417,7 +460,13 @@ export class ResourceListComponent {
|
||||
|
||||
// Modifier-key click → selection toggle
|
||||
if (e.metaKey || e.altKey || e.ctrlKey) {
|
||||
if (cfg.selectable) this._toggleSelection(card, /** @type {MouseEvent} */ (e));
|
||||
if (cfg.selectable) this._toggleSelection(card);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shift-click anywhere on the card → extend selection range
|
||||
if (e.shiftKey && cfg.selectable) {
|
||||
this._handleShiftSelect(card);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -454,11 +503,11 @@ export class ResourceListComponent {
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle selection state on a card and notify via `onSelectionChange`.
|
||||
* Toggle selection on a single card and notify.
|
||||
* Tracks `_lastClickedIndex` for subsequent shift-clicks.
|
||||
* @param {HTMLElement} card
|
||||
* @param {MouseEvent} _e - Reserved for future shift-click range selection.
|
||||
*/
|
||||
_toggleSelection(card, _e) {
|
||||
_toggleSelection(card) {
|
||||
const id = card.dataset.fileId || card.dataset.folderId || '';
|
||||
if (!id) return;
|
||||
|
||||
@@ -474,13 +523,96 @@ export class ResourceListComponent {
|
||||
this._selected.delete(id);
|
||||
}
|
||||
|
||||
if (this._cfg.onSelectionChange) {
|
||||
// Record position for the next shift-click
|
||||
const items = [...this._container.querySelectorAll('.file-item')];
|
||||
this._lastClickedIndex = items.indexOf(card);
|
||||
|
||||
this._syncSelectAllCheckbox();
|
||||
this._notifySelectionChange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend the selection from `_lastClickedIndex` to `card` (inclusive).
|
||||
* If no previous click exists, falls back to a plain toggle.
|
||||
* @param {HTMLElement} card
|
||||
*/
|
||||
_handleShiftSelect(card) {
|
||||
const items = /** @type {HTMLElement[]} */ ([...this._container.querySelectorAll('.file-item')]);
|
||||
const index = items.indexOf(card);
|
||||
|
||||
if (this._lastClickedIndex >= 0 && index >= 0) {
|
||||
const start = Math.min(this._lastClickedIndex, index);
|
||||
const end = Math.max(this._lastClickedIndex, index);
|
||||
for (let i = start; i <= end; i++) {
|
||||
const el = items[i];
|
||||
const id = el.dataset.fileId || el.dataset.folderId || '';
|
||||
if (!id) continue;
|
||||
el.classList.add('selected');
|
||||
const cb = /** @type {HTMLInputElement | null} */ (el.querySelector('.item-checkbox'));
|
||||
if (cb) cb.checked = true;
|
||||
this._selected.add(id);
|
||||
}
|
||||
} else {
|
||||
this._toggleSelection(card);
|
||||
return;
|
||||
}
|
||||
|
||||
this._lastClickedIndex = index;
|
||||
this._syncSelectAllCheckbox();
|
||||
this._notifySelectionChange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the select-all checkbox in the container header and wire its
|
||||
* `change` event. Called after every `render()`.
|
||||
*/
|
||||
_wireSelectAll() {
|
||||
if (!this._cfg.selectable) return;
|
||||
const cb = /** @type {HTMLInputElement | null} */ (this._container.querySelector('#select-all-checkbox'));
|
||||
if (!cb) return;
|
||||
// Replace with a fresh listener to avoid duplicates across re-renders
|
||||
const fresh = /** @type {HTMLInputElement} */ (cb.cloneNode(true));
|
||||
cb.parentNode?.replaceChild(fresh, cb);
|
||||
fresh.addEventListener('change', () => {
|
||||
if (fresh.checked) {
|
||||
this.selectAll();
|
||||
} else {
|
||||
this.clearSelection();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the three-state select-all checkbox in the list header.
|
||||
* Checked = all selected, indeterminate = some selected, unchecked = none.
|
||||
*/
|
||||
_syncSelectAllCheckbox() {
|
||||
const cb = /** @type {HTMLInputElement | null} */ (this._container.querySelector('#select-all-checkbox'));
|
||||
if (!cb) return;
|
||||
const total = this._container.querySelectorAll('.file-item').length;
|
||||
if (total === 0) {
|
||||
cb.checked = false;
|
||||
cb.indeterminate = false;
|
||||
} else if (this._selected.size >= total) {
|
||||
cb.checked = true;
|
||||
cb.indeterminate = false;
|
||||
} else if (this._selected.size > 0) {
|
||||
cb.checked = false;
|
||||
cb.indeterminate = true;
|
||||
} else {
|
||||
cb.checked = false;
|
||||
cb.indeterminate = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Build the selected-items array and fire `onSelectionChange`. */
|
||||
_notifySelectionChange() {
|
||||
if (!this._cfg.onSelectionChange) return;
|
||||
/** @type {Array<FileItem|FolderItem>} */
|
||||
const selectedItems = [...this._selected].flatMap((sid) => {
|
||||
const item = this._items.get(sid);
|
||||
const selectedItems = [...this._selected].flatMap((id) => {
|
||||
const item = this._items.get(id);
|
||||
return item ? [item] : [];
|
||||
});
|
||||
this._cfg.onSelectionChange(selectedItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
/**
|
||||
* OxiCloud - Multi-Select & Batch Actions Module
|
||||
* OxiCloud — Batch Toolbar Module
|
||||
*
|
||||
* Adds checkboxes to grid and list views, replaces the list-view header
|
||||
* with a NextCloud-style selection bar when items are selected, and
|
||||
* provides batch delete / move / download / favorites operations.
|
||||
* Manages the floating selection bar that appears when items are selected,
|
||||
* and executes batch operations (delete, move, download, favorites).
|
||||
*
|
||||
* Selection state (_selected, handleToggleItem, selectAll, …) is kept here
|
||||
* while the main file manager still uses its own delegation (ui.js).
|
||||
* Once ui.js is migrated to ResourceListComponent (plan step B5), all
|
||||
* selection mechanics will live in the component and this module will
|
||||
* shrink to only the toolbar UI and batch-operation API calls.
|
||||
*/
|
||||
|
||||
// TODO: rename into selection-bar ?
|
||||
// TODO: merge with photo part
|
||||
|
||||
import { loadFiles } from '../../app/filesView.js';
|
||||
import { app } from '../../app/state.js';
|
||||
import { showConfirmDialog, ui } from '../../app/ui.js';
|
||||
@@ -22,7 +24,7 @@ import { getAuthHeaders } from './fileOperations.js';
|
||||
* @import {BatchResult} from './fileOperations.js'
|
||||
*/
|
||||
|
||||
const multiSelect = {
|
||||
const batchToolbar = {
|
||||
/** @type {Map<String, LightItem>} items: Map<id, { id, name, type, parentId }> */
|
||||
|
||||
_selected: new Map(),
|
||||
@@ -536,4 +538,4 @@ const multiSelect = {
|
||||
}
|
||||
};
|
||||
|
||||
export { multiSelect };
|
||||
export { batchToolbar };
|
||||
@@ -18,7 +18,7 @@ import { musicView } from '../library/music.js';
|
||||
import { fileSharing } from '../sharing/fileSharing.js';
|
||||
import { fileOps } from './fileOperations.js';
|
||||
import { inlineViewer } from './inlineViewer.js';
|
||||
import { multiSelect } from './multiSelect.js';
|
||||
import { batchToolbar } from './batchToolbar.js';
|
||||
import { wopiEditor } from './wopiEditor.js';
|
||||
|
||||
/**
|
||||
@@ -330,8 +330,8 @@ const contextMenus = {
|
||||
|
||||
// Copy button handler
|
||||
copyConfirmBtn.addEventListener('click', async () => {
|
||||
// Batch copy mode (from multiSelect)
|
||||
if (app.moveDialogMode === 'batch' && multiSelect) {
|
||||
// Batch copy mode (from batchToolbar)
|
||||
if (app.moveDialogMode === 'batch' && batchToolbar) {
|
||||
const targetId = app.selectedTargetFolderId;
|
||||
const items = app.batchMoveItems || [];
|
||||
|
||||
@@ -341,10 +341,10 @@ const contextMenus = {
|
||||
const result = await fileOps.batchCopy(fileIds, folderIds, targetId);
|
||||
|
||||
this.closeMoveDialog();
|
||||
multiSelect.clear();
|
||||
batchToolbar.clear();
|
||||
loadFiles();
|
||||
|
||||
multiSelect.showBatchResult('copy', result);
|
||||
batchToolbar.showBatchResult('copy', result);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -363,8 +363,8 @@ const contextMenus = {
|
||||
});
|
||||
|
||||
moveConfirmBtn.addEventListener('click', async () => {
|
||||
// Batch move mode (from multiSelect)
|
||||
if (app.moveDialogMode === 'batch' && multiSelect) {
|
||||
// Batch move mode (from batchToolbar)
|
||||
if (app.moveDialogMode === 'batch' && batchToolbar) {
|
||||
const targetId = app.selectedTargetFolderId;
|
||||
const items = app.batchMoveItems || [];
|
||||
|
||||
@@ -374,9 +374,9 @@ const contextMenus = {
|
||||
const result = await fileOps.batchMove(fileIds, folderIds, targetId);
|
||||
|
||||
this.closeMoveDialog();
|
||||
multiSelect.clear();
|
||||
batchToolbar.clear();
|
||||
loadFiles();
|
||||
multiSelect.showBatchResult('move', result);
|
||||
batchToolbar.showBatchResult('move', result);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import { ui } from '../../app/ui.js';
|
||||
import { getCsrfHeaders } from '../../core/csrf.js';
|
||||
import { i18n } from '../../core/i18n.js';
|
||||
import { multiSelect } from '../files/multiSelect.js';
|
||||
import { batchToolbar } from '../files/batchToolbar.js';
|
||||
import * as pathTooltip from '../pathTooltip.js';
|
||||
|
||||
/** @import {FavoriteItem, FileItem, FolderItem} from '../../core/types.js' */
|
||||
@@ -181,7 +181,7 @@ const favorites = {
|
||||
ui.resetFilesList(); // ensure also list visible & error hidden
|
||||
// wire buttons & select-all-checkbox as list header has changed in ui.resetFilesList()
|
||||
// FIXME: this case is not easy to understand, should apply better implementation
|
||||
multiSelect.init();
|
||||
batchToolbar.init();
|
||||
|
||||
ui.updateBreadcrumb();
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
import { ui } from '../../app/ui.js';
|
||||
import { getCsrfHeaders } from '../../core/csrf.js';
|
||||
import { i18n } from '../../core/i18n.js';
|
||||
import { multiSelect } from '../files/multiSelect.js';
|
||||
import { batchToolbar } from '../files/batchToolbar.js';
|
||||
import * as pathTooltip from '../pathTooltip.js';
|
||||
|
||||
/** @import {FileItem, FolderItem, ItemTypeEnum, RecentItem} from '../../core/types.js' */
|
||||
@@ -111,9 +111,9 @@ const recent = {
|
||||
</div>
|
||||
`;
|
||||
|
||||
if (multiSelect) {
|
||||
multiSelect.clear();
|
||||
multiSelect.init(); // this will wire buttons & select-all-checkbox
|
||||
if (batchToolbar) {
|
||||
batchToolbar.clear();
|
||||
batchToolbar.init(); // this will wire buttons & select-all-checkbox
|
||||
}
|
||||
ui.updateBreadcrumb();
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
import { ui } from '../../app/ui.js';
|
||||
import { i18n } from '../../core/i18n.js';
|
||||
import { multiSelect } from '../../features/files/multiSelect.js';
|
||||
import { batchToolbar } from '../../features/files/batchToolbar.js';
|
||||
import { ownerTooltip } from '../../features/ownerTooltip.js';
|
||||
import { grants } from '../../model/grants.js';
|
||||
import { systemUsers } from '../../model/systemUsers.js';
|
||||
@@ -52,7 +52,7 @@ const sharedWithMeView = {
|
||||
|
||||
// Standard files-view setup: clear list, show container, init multiselect
|
||||
ui.resetFilesList();
|
||||
multiSelect.init();
|
||||
batchToolbar.init();
|
||||
ui.updateBreadcrumb();
|
||||
|
||||
await this._loadPage();
|
||||
|
||||
Reference in New Issue
Block a user