Add sort toggle for domain list (A-Z vs feed count)

Added ability to toggle between alphabetical and feed count sorting when
viewing domains under a TLD. Includes UI toggle in breadcrumb area and
backend support for the sort parameter.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
primal
2026-01-29 13:09:31 -05:00
parent a8c73bb540
commit f7535a277f
2 changed files with 36 additions and 4 deletions
+9 -3
View File
@@ -1226,6 +1226,7 @@ func (c *Crawler) handleAPIFilter(w http.ResponseWriter, r *http.Request) {
domainStatus := r.URL.Query().Get("domainStatus")
languages := r.URL.Query().Get("languages") // comma-separated list
show := r.URL.Query().Get("show") // "feeds" or "domains"
sort := r.URL.Query().Get("sort") // "alpha" or "feeds"
limit := 100
offset := 0
@@ -1262,11 +1263,11 @@ func (c *Crawler) handleAPIFilter(w http.ResponseWriter, r *http.Request) {
if show == "feeds" {
c.filterFeeds(w, tld, domain, feedStatus, langList, limit, offset)
} else {
c.filterDomains(w, tld, domainStatus, limit, offset)
c.filterDomains(w, tld, domainStatus, sort, limit, offset)
}
}
func (c *Crawler) filterDomains(w http.ResponseWriter, tld, status string, limit, offset int) {
func (c *Crawler) filterDomains(w http.ResponseWriter, tld, status, sort string, limit, offset int) {
var args []interface{}
argNum := 1
query := `
@@ -1290,7 +1291,12 @@ func (c *Crawler) filterDomains(w http.ResponseWriter, tld, status string, limit
argNum++
}
query += fmt.Sprintf(" ORDER BY d.host ASC LIMIT $%d OFFSET $%d", argNum, argNum+1)
// Sort by feed count descending or alphabetically
if sort == "feeds" {
query += fmt.Sprintf(" ORDER BY feed_count DESC, d.host ASC LIMIT $%d OFFSET $%d", argNum, argNum+1)
} else {
query += fmt.Sprintf(" ORDER BY d.host ASC LIMIT $%d OFFSET $%d", argNum, argNum+1)
}
args = append(args, limit, offset)
rows, err := c.db.Query( query, args...)
+27 -1
View File
@@ -16,6 +16,7 @@ function initDashboard() {
let isLoadingMore = false;
let availableLanguages = [];
let selectedLanguages = new Set();
let sortBy = 'alpha'; // 'alpha' or 'feeds'
// Update command input to reflect current filters
function updateCommandInput() {
@@ -81,7 +82,20 @@ function initDashboard() {
parts.push('<span class="bc-item" data-action="clearLang" style="cursor: pointer; color: #f0f;">lang:' + escapeHtml(Array.from(selectedLanguages).join(',')) + ' ✕</span>');
}
breadcrumb.innerHTML = parts.join(' <span style="color: #666;">/</span> ');
// Add sort toggle on the right if viewing domains
let sortToggle = '';
if (currentFilters.tld && !currentFilters.domain && !currentFilters.feedStatus) {
const alphaStyle = sortBy === 'alpha' ? 'color: #0f0;' : 'color: #666;';
const feedsStyle = sortBy === 'feeds' ? 'color: #0f0;' : 'color: #666;';
sortToggle = '<span style="margin-left: auto; font-size: 12px;">' +
'<span class="sort-toggle" data-sort="alpha" style="cursor: pointer; ' + alphaStyle + '">A-Z</span>' +
'<span style="color: #444;"> | </span>' +
'<span class="sort-toggle" data-sort="feeds" style="cursor: pointer; ' + feedsStyle + '">#feeds</span>' +
'</span>';
}
breadcrumb.innerHTML = '<div style="display: flex; align-items: center;">' +
parts.join(' <span style="color: #666;">/</span> ') + sortToggle + '</div>';
breadcrumb.style.display = parts.length > 1 ? 'block' : 'none';
// Add click handlers
@@ -105,6 +119,17 @@ function initDashboard() {
selectedLanguages.clear();
updateLangButton();
updateLangDropdown();
}
});
});
// Add sort toggle handlers
breadcrumb.querySelectorAll('.sort-toggle').forEach(el => {
el.addEventListener('click', () => {
const newSort = el.dataset.sort;
if (newSort !== sortBy) {
sortBy = newSort;
executeFilters();
executeFilters();
}
});
@@ -353,6 +378,7 @@ function initDashboard() {
if (hasLang) params.set('languages', Array.from(selectedLanguages).join(','));
if (showFeeds) params.set('show', 'feeds');
else if (showDomains) params.set('show', 'domains');
if (sortBy) params.set('sort', sortBy);
// Fetch TLD stats if viewing a TLD
let tldStatsHtml = '';