Merge pull request #298 from EdouardVanbelle/feat/buttons
This commit is contained in:
@@ -37,15 +37,11 @@
|
||||
.batch-selection-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: var(--color-multiselect-bg);
|
||||
color: var(--color-multiselect-text);
|
||||
padding: 10px 20px;
|
||||
border-radius: 12px;
|
||||
margin: 0 0 12px;
|
||||
height: 60px;
|
||||
overflow: hidden;
|
||||
transform: translateY(-8px);
|
||||
transition:
|
||||
opacity 0.2s,
|
||||
max-height 0.25s,
|
||||
@@ -55,12 +51,6 @@
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.batch-bar-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.batch-bar-close {
|
||||
background: none;
|
||||
border: none;
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
flex: auto;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
|
||||
+1
-36
@@ -210,42 +210,7 @@
|
||||
<h1 class="page-title" data-i18n="nav.files">Files</h1>
|
||||
|
||||
<div class="page-sticky-header" id="page-sticky-header">
|
||||
<div class="actions-bar" id="actions-bar">
|
||||
|
||||
<div class="action-buttons" id="action-buttons">
|
||||
<div class="upload-dropdown" id="upload-dropdown">
|
||||
<button class="btn btn-primary" id="upload-btn">
|
||||
<i class="fas fa-cloud-upload-alt"></i>
|
||||
<span data-i18n="actions.upload">Upload</span>
|
||||
<i class="fas fa-caret-down upload-caret"></i>
|
||||
</button>
|
||||
<div class="upload-dropdown-menu" id="upload-dropdown-menu">
|
||||
<button class="upload-dropdown-item" id="upload-files-btn">
|
||||
<i class="fas fa-file"></i>
|
||||
<span data-i18n="actions.upload_files">Upload files</span>
|
||||
</button>
|
||||
<button class="upload-dropdown-item" id="upload-folder-btn">
|
||||
<i class="fas fa-folder-open"></i>
|
||||
<span data-i18n="actions.upload_folder">Upload folder</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-secondary" id="new-folder-btn">
|
||||
<i class="fas fa-folder-plus"></i>
|
||||
<span data-i18n="actions.new_folder">New folder</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="batch-selection-bar" class="batch-selection-bar hidden"></div>
|
||||
<div class="actions-bar" id="actions-bar"><!-- content will be set up by JS --></div>
|
||||
|
||||
<div class="breadcrumb">
|
||||
<span class="breadcrumb-item" data-i18n="breadcrumb.home">Home</span>
|
||||
|
||||
@@ -107,6 +107,7 @@ async function rebuildBreadCrumb() {
|
||||
app.currentFolderInfo = currentFolderInfo;
|
||||
}
|
||||
|
||||
// TODO split load() vs view()
|
||||
/**
|
||||
* Files view loading logic
|
||||
*
|
||||
|
||||
+53
-36
@@ -38,9 +38,51 @@ let uploadDropdownDocumentClickHandler = null;
|
||||
let uploadDropdownBindingsController = null;
|
||||
let actionsBarDelegationBound = false;
|
||||
|
||||
const _multiSelectButons = `
|
||||
<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">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
<span class="batch-bar-count" id="batch-bar-count"></span>
|
||||
</div>
|
||||
<div class="batch-selection-info">
|
||||
<div class="batch-bar-actions">
|
||||
<button class="batch-btn" id="batch-fav" title="Add to favorites" data-i18n-title="batch.add_favorites">
|
||||
<i class="fas fa-star"></i>
|
||||
<span data-i18n="batch.add_favorites">Add to favorites</span>
|
||||
</button>
|
||||
<button class="batch-btn" id="batch-move" title="Move or copy" data-i18n-title="batch.move_copy">
|
||||
<i class="fas fa-arrows-alt"></i>
|
||||
<span data-i18n="batch.move_copy">Move or copy</span>
|
||||
</button>
|
||||
<button class="batch-btn" id="batch-download" title="Download" data-i18n-title="actions.download">
|
||||
<i class="fas fa-download"></i>
|
||||
<span data-i18n="actions.download">Download</span>
|
||||
</button>
|
||||
<button class="batch-btn batch-btn-danger" id="batch-delete" title="Delete" data-i18-title="actions.delete">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
<span data-i18n="actions.delete">Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const _toggleButtons = `
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const ACTIONS_BAR_TEMPLATES = {
|
||||
files: `
|
||||
<div class="action-buttons">
|
||||
<div class="action-buttons" id="default-buttons">
|
||||
<div class="upload-dropdown" id="upload-dropdown">
|
||||
<button class="btn btn-primary" id="upload-btn">
|
||||
<i class="fas fa-cloud-upload-alt icon-mr"></i>
|
||||
@@ -63,57 +105,32 @@ const ACTIONS_BAR_TEMPLATES = {
|
||||
<span data-i18n="actions.new_folder">New folder</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
${_multiSelectButons}
|
||||
${_toggleButtons}
|
||||
`,
|
||||
trash: `
|
||||
<div class="action-buttons">
|
||||
<div class="action-buttons" id="default-buttons">
|
||||
<button class="btn btn-danger" id="empty-trash-btn">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
<span data-i18n="trash.empty_trash">Empty trash</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
${_toggleButtons}
|
||||
`,
|
||||
favorites: `
|
||||
<div class="action-buttons"></div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="action-buttons" id="default-buttons"></div>
|
||||
${_multiSelectButons}
|
||||
${_toggleButtons}
|
||||
`,
|
||||
recent: `
|
||||
<div class="action-buttons">
|
||||
<div class="action-buttons" id="default-buttons">
|
||||
<button class="btn btn-secondary" id="clear-recent-btn">
|
||||
<i class="fas fa-broom icon-mr"></i>
|
||||
<span data-i18n="actions.clear_recent">Clear recent</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="view-toggle">
|
||||
<button class="toggle-btn active" id="grid-view-btn" title="Grid view">
|
||||
<i class="fas fa-th"></i>
|
||||
</button>
|
||||
<button class="toggle-btn" id="list-view-btn" title="List view">
|
||||
<i class="fas fa-list"></i>
|
||||
</button>
|
||||
</div>
|
||||
${_multiSelectButons}
|
||||
${_toggleButtons}
|
||||
`
|
||||
};
|
||||
|
||||
|
||||
@@ -1309,6 +1309,9 @@ const ui = {
|
||||
|
||||
filesList.classList.remove('hidden');
|
||||
filesContainerError?.classList.add('hidden');
|
||||
|
||||
// apply hook as header changed
|
||||
multiSelect.init();
|
||||
},
|
||||
|
||||
showEmptyList() {
|
||||
|
||||
@@ -230,51 +230,12 @@ const multiSelect = {
|
||||
this._syncSelectAllCheckbox();
|
||||
},
|
||||
|
||||
// ── Selection bar (replaces list-header when items selected) ────
|
||||
|
||||
/**
|
||||
* Build the inner HTML for the selection bar that replaces the
|
||||
* normal list-header columns (Name / Type / Size / Modified).
|
||||
*/
|
||||
_buildSelectionBarHTML() {
|
||||
//FIXME: should support i18n lang change
|
||||
|
||||
return `
|
||||
<div x-class="batch-bar-left" class="list-header-checkbox">
|
||||
<button class="batch-bar-close" id="batch-grid-close" title="Cancel selection">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
<span class="batch-bar-count" id="batch-bar-count"></span>
|
||||
</div>
|
||||
<div class="batch-selection-info">
|
||||
<div class="batch-bar-actions">
|
||||
<button class="batch-btn" id="batch-fav" title="Add to favorites" data-i18n-title="batch.add_favorites">
|
||||
<i class="fas fa-star"></i>
|
||||
<span data-i18n="batch.add_favorites">Add to favorites</span>
|
||||
</button>
|
||||
<button class="batch-btn" id="batch-move" title="Move or copy" data-i18n-title="batch.move_copy">
|
||||
<i class="fas fa-arrows-alt"></i>
|
||||
<span data-i18n="batch.move_copy">Move or copy</span>
|
||||
</button>
|
||||
<button class="batch-btn" id="batch-download" title="Download" data-i18n-title="actions.download">
|
||||
<i class="fas fa-download"></i>
|
||||
<span data-i18n="actions.download">Download</span>
|
||||
</button>
|
||||
<button class="batch-btn batch-btn-danger" id="batch-delete" title="Delete" data-i18-title="actions.delete">
|
||||
<i class="fas fa-trash-alt"></i>
|
||||
<span data-i18n="actions.delete">Delete</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
|
||||
/** Main UI sync — called after every selection change */
|
||||
_syncUI() {
|
||||
const n = this._selected.size;
|
||||
|
||||
const batchSelectionBar = document.getElementById('batch-selection-bar');
|
||||
const actionsBar = document.getElementById('actions-bar');
|
||||
const multiSelectButtons = document.getElementById('multi-select-buttons');
|
||||
const defaultButtons = document.getElementById('default-buttons');
|
||||
|
||||
if (n > 0) {
|
||||
this._barVisible = true;
|
||||
@@ -282,16 +243,14 @@ const multiSelect = {
|
||||
const countText = n === 1 ? this._t('batch.one_selected') || '1 item selected' : this._t('batch.n_selected', { count: n }) || `${n} items selected`;
|
||||
document.getElementById('batch-bar-count').innerText = countText;
|
||||
|
||||
actionsBar.classList.add('hidden');
|
||||
|
||||
batchSelectionBar.classList.remove('hidden');
|
||||
defaultButtons?.classList.add('hidden');
|
||||
multiSelectButtons?.classList.remove('hidden');
|
||||
} else {
|
||||
this._barVisible = false;
|
||||
|
||||
// Hide grid bar
|
||||
batchSelectionBar.classList.add('hidden');
|
||||
|
||||
if (actionsBar.dataset.mode !== 'hidden') actionsBar.classList.remove('hidden');
|
||||
multiSelectButtons?.classList.add('hidden');
|
||||
defaultButtons?.classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Sync individual item checkboxes
|
||||
@@ -306,7 +265,7 @@ const multiSelect = {
|
||||
const move = document.getElementById('batch-move');
|
||||
const dl = document.getElementById('batch-download');
|
||||
const fav = document.getElementById('batch-fav');
|
||||
const closeBtn = document.getElementById('batch-grid-close');
|
||||
const closeBtn = document.getElementById('batch-selection-close');
|
||||
if (del) del.onclick = () => this.batchDelete();
|
||||
if (move) move.onclick = () => this.batchMove();
|
||||
if (dl) dl.onclick = () => this.batchDownload();
|
||||
@@ -515,12 +474,6 @@ const multiSelect = {
|
||||
if (e.key === 'Delete' && this.hasSelection) this.batchDelete();
|
||||
});
|
||||
|
||||
const batchSelectionBar = document.getElementById('batch-selection-bar');
|
||||
batchSelectionBar.innerHTML = this._buildSelectionBarHTML();
|
||||
|
||||
if (i18n?.translateElement) {
|
||||
i18n.translateElement(batchSelectionBar);
|
||||
}
|
||||
this._wireBarButtons();
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user