Proper pagination

This commit is contained in:
2026-02-25 18:25:00 +08:00
parent 8e8269d12b
commit eaabc0114c
6 changed files with 153 additions and 30 deletions
+67 -6
View File
@@ -192,8 +192,66 @@ final tasksProvider = StreamProvider<List<Task>>((ref) {
.toList();
}
// Sort: queue_order ASC, then created_at ASC
// Sort by status groups then within-group ordering:
// 1. queued order by priority (desc), then queue_order (asc), then created_at
// 2. in_progress preserve recent order (created_at asc)
// 3. completed order by numeric task_number when available (asc)
// 4. other statuses fallback to queue_order then created_at
final statusRank = (String s) {
switch (s) {
case 'queued':
return 0;
case 'in_progress':
return 1;
case 'completed':
return 2;
default:
return 3;
}
};
int? _parseTaskNumber(Task t) {
final tn = t.taskNumber;
if (tn == null) return null;
final m = RegExp(r'\d+').firstMatch(tn);
if (m == null) return null;
return int.tryParse(m.group(0)!);
}
list.sort((a, b) {
final ra = statusRank(a.status);
final rb = statusRank(b.status);
final rcmp = ra.compareTo(rb);
if (rcmp != 0) return rcmp;
// Same status: apply within-group ordering
if (ra == 0) {
// queued: higher priority first, then queue_order asc, then created_at
final pcmp = b.priority.compareTo(a.priority);
if (pcmp != 0) return pcmp;
final aOrder = a.queueOrder ?? 0x7fffffff;
final bOrder = b.queueOrder ?? 0x7fffffff;
final qcmp = aOrder.compareTo(bOrder);
if (qcmp != 0) return qcmp;
return a.createdAt.compareTo(b.createdAt);
}
if (ra == 1) {
// in_progress: keep older first
return a.createdAt.compareTo(b.createdAt);
}
if (ra == 2) {
// completed: prefer numeric task_number DESC when present
final an = _parseTaskNumber(a);
final bn = _parseTaskNumber(b);
if (an != null && bn != null) return bn.compareTo(an);
if (an != null) return -1;
if (bn != null) return 1;
return b.createdAt.compareTo(a.createdAt);
}
// fallback: queue_order then created_at
final aOrder = a.queueOrder ?? 0x7fffffff;
final bOrder = b.queueOrder ?? 0x7fffffff;
final cmp = aOrder.compareTo(bOrder);
@@ -201,11 +259,14 @@ final tasksProvider = StreamProvider<List<Task>>((ref) {
return a.createdAt.compareTo(b.createdAt);
});
// Pagination (server-side semantics emulated client-side)
final start = query.offset;
final end = (start + query.limit).clamp(0, list.length);
if (start >= list.length) return <Task>[];
return list.sublist(start, end);
// Return the full filtered & sorted list to allow the UI layer to
// perform pagination (desktop PaginatedDataTable expects the full
// row count so it can render pagination controls reliably). The
// Supabase stream currently delivers all rows and the provider
// applies filtering/sorting; leaving pagination to the UI avoids
// off-by-one issues where a full page of results would hide the
// presence of a next page.
return list;
});
});