+
-
+
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js
index 4423382..a5c950a 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/plugins/bookmarks.js
@@ -38,10 +38,13 @@ function bmCanControl() {
);
}
-// Show/hide the Add Bookmark button based on the current auth role.
+// Show/hide the Add Bookmark / Select All buttons based on the current auth role.
function bmSyncAccess() {
+ const canCtrl = bmCanControl();
const addBtn = document.getElementById("bm-add-btn");
- if (addBtn) addBtn.style.display = bmCanControl() ? "" : "none";
+ const selectAllBtn = document.getElementById("bm-select-all-btn");
+ if (addBtn) addBtn.style.display = canCtrl ? "" : "none";
+ if (selectAllBtn) selectAllBtn.style.display = canCtrl ? "" : "none";
}
async function bmFetch(categoryFilter) {
@@ -427,6 +430,11 @@ function bmUpdateSelectionUi() {
if (moveWrap) moveWrap.style.display = visible ? "" : "none";
if (moveCountEl) moveCountEl.textContent = count;
if (visible) bmPopulateMoveTarget();
+ const selectAllBtn = document.getElementById("bm-select-all-btn");
+ if (selectAllBtn && bmCanControl()) {
+ const allSelected = bmFilteredList.length > 0 && bmFilteredList.every((bm) => bmSelected.has(bm.id));
+ selectAllBtn.textContent = allSelected ? "Deselect All" : "Select All";
+ }
}
/** Populate the move-target dropdown with all scopes except the current one. */
@@ -617,6 +625,22 @@ function bmPopulateScopePicker() {
bmUpdateSelectionUi();
});
+ // Select All (across all pages) button
+ document.getElementById("bm-select-all-btn").addEventListener("click", () => {
+ const allSelected = bmFilteredList.length > 0 && bmFilteredList.every((bm) => bmSelected.has(bm.id));
+ if (allSelected) {
+ bmSelected.clear();
+ } else {
+ bmFilteredList.forEach((bm) => bmSelected.add(bm.id));
+ }
+ // Sync visible page checkboxes
+ document.querySelectorAll(".bm-row-sel").forEach((cb) => {
+ cb.checked = bmSelected.has(cb.dataset.bmId);
+ });
+ bmSyncSelectAllCheckbox();
+ bmUpdateSelectionUi();
+ });
+
// Delete Selected button
document.getElementById("bm-del-selected-btn").addEventListener("click", () => {
bmDeleteSelected();
diff --git a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css
index 7096ac1..11eea84 100644
--- a/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css
+++ b/src/trx-client/trx-frontend/trx-frontend-http/assets/web/style.css
@@ -3720,6 +3720,21 @@ button:focus-visible, input:focus-visible, select:focus-visible {
background: var(--btn-bg);
cursor: pointer;
}
+.bm-move-wrap {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35rem;
+}
+.bm-toolbar-btn {
+ white-space: nowrap;
+ font-size: 0.78rem;
+ padding: 0.25rem 0.6rem;
+ border-radius: 0.25rem;
+ border: 1px solid var(--border-light);
+ background: var(--btn-bg);
+ color: var(--text-heading);
+ cursor: pointer;
+}
.bm-empty {
padding: 2rem 1rem;