diff --git a/public/js/data-store.js b/public/js/data-store.js index 1eb496d..a55f8aa 100644 --- a/public/js/data-store.js +++ b/public/js/data-store.js @@ -22,7 +22,9 @@ document.addEventListener('alpine:init', () => { filters: { account: 'all', family: 'all', - search: '' + search: '', + sortCol: 'avgQuota', + sortAsc: true }, // Settings for calculation @@ -177,20 +179,52 @@ document.addEventListener('alpine:init', () => { resetIn: minResetTime ? window.utils.formatTimeUntil(minResetTime) : '-', quotaInfo, pinned: !!config.pinned, - hidden: !!isHidden // Use computed visibility + hidden: !!isHidden, // Use computed visibility + activeCount: quotaInfo.filter(q => q.pct > 0).length }); }); - // Sort: Pinned first, then by avgQuota (descending) + // Sort: Pinned first, then by selected column + const sortCol = this.filters.sortCol; + const sortAsc = this.filters.sortAsc; + this.quotaRows = rows.sort((a, b) => { if (a.pinned !== b.pinned) return a.pinned ? -1 : 1; - return b.avgQuota - a.avgQuota; + + let valA = a[sortCol]; + let valB = b[sortCol]; + + // Handle nulls (always push to bottom) + if (valA === valB) return 0; + if (valA === null || valA === undefined) return 1; + if (valB === null || valB === undefined) return -1; + + if (typeof valA === 'string' && typeof valB === 'string') { + return sortAsc ? valA.localeCompare(valB) : valB.localeCompare(valA); + } + + return sortAsc ? valA - valB : valB - valA; }); // Trigger Dashboard Update if active // Ideally dashboard watches this store. }, + setSort(col) { + if (this.filters.sortCol === col) { + this.filters.sortAsc = !this.filters.sortAsc; + } else { + this.filters.sortCol = col; + // Default sort direction: Descending for numbers/stats, Ascending for text/time + if (['avgQuota', 'activeCount'].includes(col)) { + this.filters.sortAsc = false; + } else { + this.filters.sortAsc = true; + } + } + this.computeQuotaRows(); + }, + getModelFamily(modelId) { const lower = modelId.toLowerCase(); if (lower.includes('claude')) return 'claude'; diff --git a/public/views/models.html b/public/views/models.html index 8b2b1d6..5efcde1 100644 --- a/public/views/models.html +++ b/public/views/models.html @@ -94,14 +94,60 @@ :class="{'table-xs': $store.settings.compact, 'table-sm': !$store.settings.compact}"> - Stat - Model Identity - Global - Quota - Next Reset + +
+ Stat +
+ + +
+ Model Identity + + + +
+ + +
+ Global Quota + + + +
+ + +
+ Next Reset + + + +
+ + +
+ Account Distribution + + + +
- Account - Distribution Actions @@ -143,20 +189,20 @@ -
+
-
+