[feat](trx-frontend-http): add Select All bookmarks across pages, fix move wrap styling

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-24 20:52:01 +01:00
parent abe8529332
commit de5f27f75e
3 changed files with 44 additions and 4 deletions
@@ -379,10 +379,11 @@
</select>
<input type="search" id="bm-text-filter" class="status-input" placeholder="Search bookmarks…" aria-label="Search bookmarks" />
<button id="bm-add-btn" type="button" class="bm-add-btn" style="display:none;">+ Add Bookmark</button>
<button id="bm-select-all-btn" type="button" class="bm-toolbar-btn" style="display:none;">Select All</button>
<button id="bm-del-selected-btn" type="button" class="bm-del-btn" style="display:none;">Delete Selected (<span id="bm-del-selected-count">0</span>)</button>
<span id="bm-move-selected-wrap" style="display:none;">
<span id="bm-move-selected-wrap" class="bm-move-wrap" style="display:none;">
<select id="bm-move-target" class="status-input" aria-label="Move destination"></select>
<button id="bm-move-selected-btn" type="button" class="bm-add-btn">Move (<span id="bm-move-selected-count">0</span>)</button>
<button id="bm-move-selected-btn" type="button" class="bm-toolbar-btn">Move (<span id="bm-move-selected-count">0</span>)</button>
</span>
</div>
<div id="bm-form-wrap" style="display:none;">
@@ -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();
@@ -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;