mirror of
https://github.com/wahyd4/links.git
synced 2026-08-09 05:06:16 +10:00
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:
@@ -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
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user