fix(home): restore tbody binding, sticky mobile delete bar, 20-row recent-first list

- Fix Uncaught ReferenceError: tbody is not defined — the client-side filter
  rewrite dropped the const tbody declaration still used by load-more
- Mobile: Delete Selected becomes a sticky frosted bottom bar (safe-area
  aware); disabled (grayed) until a row is selected, then red
- Mobile: library search input full-width 48px (primary interaction)
- Default list: 20 rows (was 50) sorted by updated_at desc (recent first)
  instead of click_count; load-more keeps paging +20
This commit is contained in:
OpenClaw Sub-agent
2026-08-02 11:35:51 +10:00
parent f3bf4089f6
commit 540733699e
2 changed files with 28 additions and 9 deletions
+21 -2
View File
@@ -208,6 +208,10 @@
.apple-btn-primary:hover { background: var(--apple-blue-hover); color: #fff; }
.apple-btn-danger { background: transparent; color: var(--apple-red); border: 1px solid rgba(255, 59, 48, 0.4); }
.apple-btn-danger:hover { background: rgba(255, 59, 48, 0.08); }
.apple-btn-danger:disabled {
opacity: 0.45; color: var(--apple-gray); border-color: rgba(0, 0, 0, 0.12);
cursor: default; pointer-events: none; background: transparent;
}
/* ---------- Link library (table) ---------- */
.library-header {
@@ -579,7 +583,19 @@
/* ---------- Small screens ---------- */
@media (max-width: 640px) {
.library-header { padding: 1.35rem 1.1rem 1rem; }
.library-footer { padding: 1rem 1.1rem 1.25rem; }
.library-footer {
position: sticky; bottom: 0; z-index: 5;
background: rgba(245, 245, 247, 0.88);
-webkit-backdrop-filter: blur(20px) saturate(180%);
backdrop-filter: blur(20px) saturate(180%);
border-top: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 0 0 var(--apple-radius-lg) var(--apple-radius-lg);
margin: 0 -1.1rem -1.25rem;
padding: 0.7rem 1.1rem calc(0.7rem + env(safe-area-inset-bottom, 0px));
}
/* Search takes the full row on mobile (it is the primary interaction) */
.library-filter { flex: 1 1 100%; }
.library-filter input { width: 100%; height: 48px; font-size: 1rem; }
.apple-table thead th, .apple-table tbody td { padding-left: 0.8rem; padding-right: 0.8rem; }
.hero-stats { gap: 1.25rem; }
.posts-panel-header { padding: 1.15rem 1.1rem 0.6rem; }
@@ -965,7 +981,7 @@
{% endif %}
<div class="library-footer">
<p class="selection-hint" id="selection-hint" aria-live="polite"></p>
<button type="submit" class="apple-btn apple-btn-danger">{% trans "Delete Selected" %}</button>
<button type="submit" id="delete-selected-btn" class="apple-btn apple-btn-danger" disabled>{% trans "Delete Selected" %}</button>
</div>
</form>
</section>
@@ -1406,6 +1422,7 @@
/* ---------- Load more links ---------- */
const loadMoreBtn = document.getElementById('load-more-links');
const tbody = document.getElementById('links-table-body');
if (loadMoreBtn && tbody) {
loadMoreBtn.addEventListener('click', function () {
const offset = loadMoreBtn.dataset.offset;
@@ -1444,6 +1461,8 @@
if (!selectionHint) return;
const count = document.querySelectorAll('input[name="selected_links"]:checked').length;
selectionHint.textContent = count > 0 ? count + ' {% trans "selected" %}' : '';
const delBtn = document.getElementById('delete-selected-btn');
if (delBtn) delBtn.disabled = count === 0;
}
if (selectAll) {
+7 -7
View File
@@ -47,7 +47,7 @@ from .search_views import search_aliases, search
logger = logging.getLogger(__name__)
# Number of link rows rendered on the initial home page load / per "Load more" click.
LINKS_PAGE_SIZE = 50
LINKS_PAGE_SIZE = 20
def _ordering_for(sort_by, order):
@@ -74,14 +74,14 @@ class LinkListView(ListView):
def get_queryset(self):
queryset = super().get_queryset()
sort_by = self.request.GET.get('sort', 'click_count')
order = self.request.GET.get('order', 'asc')
sort_by = self.request.GET.get('sort', 'updated_at')
order = self.request.GET.get('order', 'desc')
return queryset.order_by(_ordering_for(sort_by, order))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['current_sort'] = self.request.GET.get('sort', 'click_count')
context['current_order'] = self.request.GET.get('order', 'asc')
context['current_sort'] = self.request.GET.get('sort', 'updated_at')
context['current_order'] = self.request.GET.get('order', 'desc')
# Modern color palette
colors = [
@@ -128,8 +128,8 @@ def load_more_links(request):
"""Return the next page of link rows (rendered as <tr> HTML) for the
home page's "Load more" button, so the initial page load doesn't have
to render the entire link table at once."""
sort_by = request.GET.get('sort', 'click_count')
order = request.GET.get('order', 'asc')
sort_by = request.GET.get('sort', 'updated_at')
order = request.GET.get('order', 'desc')
try:
offset = max(int(request.GET.get('offset', 0)), 0)
except (TypeError, ValueError):