mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Add "go to last page" and page count to notifications and devices lists
The list endpoints now return a total count alongside the page so the
front-end can show how many pages exist and offer a last-page jump.
Backend: add count(is_new) and count_devices(...) (sharing a WHERE-builder
with list_devices so page and count can't drift), wrap both list responses
in {items, total_count} structs, and register them with utoipa.
Front-end: parse the wrapper shape (dropping the fetch-one-extra trick),
add a Last-page button and a responsive "Page X of Y" / "X / Y" label to
the shared PaginationBar, and track the total in both lists. Notifications
re-sync the count on every fetch and decrement it locally on mark-read/
unread removals so the count stays accurate without a re-fetch.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
3cb104e364
commit
844d7d189c
@@ -1,12 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:frontend/theme/dimens.dart';
|
||||
import 'package:frontend/theme/gruvbox_theme.dart';
|
||||
import 'package:frontend/widgets/pagination_bar.dart';
|
||||
|
||||
void main() {
|
||||
Widget wrap(Widget child) => MaterialApp(
|
||||
theme: gruvboxDarkTheme,
|
||||
home: Scaffold(body: child),
|
||||
Widget wrap(Widget child, {Size? size}) => MediaQuery(
|
||||
data: MediaQueryData(size: size ?? const Size(1200, 800)),
|
||||
child: MaterialApp(
|
||||
theme: gruvboxDarkTheme,
|
||||
home: Scaffold(body: child),
|
||||
),
|
||||
);
|
||||
|
||||
testWidgets('disables every navigation button while loading', (tester) async {
|
||||
@@ -15,7 +19,7 @@ void main() {
|
||||
wrap(
|
||||
PaginationBar(
|
||||
currentPage: 1,
|
||||
hasNextPage: true,
|
||||
totalPages: 3,
|
||||
isLoading: true,
|
||||
onPageChanged: (page) => changedTo = page,
|
||||
),
|
||||
@@ -25,6 +29,7 @@ void main() {
|
||||
await tester.tap(find.byTooltip('Next page'));
|
||||
await tester.tap(find.byTooltip('Previous page'));
|
||||
await tester.tap(find.byTooltip('First page'));
|
||||
await tester.tap(find.byTooltip('Last page'));
|
||||
expect(changedTo, -1);
|
||||
});
|
||||
|
||||
@@ -34,7 +39,7 @@ void main() {
|
||||
wrap(
|
||||
PaginationBar(
|
||||
currentPage: 1,
|
||||
hasNextPage: true,
|
||||
totalPages: 3,
|
||||
isLoading: false,
|
||||
onPageChanged: (page) => changedTo = page,
|
||||
),
|
||||
@@ -47,4 +52,73 @@ void main() {
|
||||
await tester.tap(find.byTooltip('Previous page'));
|
||||
expect(changedTo, 0);
|
||||
});
|
||||
|
||||
testWidgets('last-page button jumps to the final page', (tester) async {
|
||||
var changedTo = -1;
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
PaginationBar(
|
||||
currentPage: 0,
|
||||
totalPages: 5,
|
||||
isLoading: false,
|
||||
onPageChanged: (page) => changedTo = page,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byTooltip('Last page'));
|
||||
expect(changedTo, 4);
|
||||
});
|
||||
|
||||
testWidgets('forward buttons disable on the last page', (tester) async {
|
||||
var changedTo = -1;
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
PaginationBar(
|
||||
currentPage: 4,
|
||||
totalPages: 5,
|
||||
isLoading: false,
|
||||
onPageChanged: (page) => changedTo = page,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byTooltip('Next page'));
|
||||
await tester.tap(find.byTooltip('Last page'));
|
||||
expect(changedTo, -1);
|
||||
});
|
||||
|
||||
testWidgets('spells out the page label on wide layouts', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
const PaginationBar(
|
||||
currentPage: 1,
|
||||
totalPages: 5,
|
||||
isLoading: false,
|
||||
onPageChanged: _noop,
|
||||
),
|
||||
size: const Size(1200, 800),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.text('Page 2 of 5'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('uses the compact page label on narrow layouts', (tester) async {
|
||||
await tester.pumpWidget(
|
||||
wrap(
|
||||
const PaginationBar(
|
||||
currentPage: 1,
|
||||
totalPages: 5,
|
||||
isLoading: false,
|
||||
onPageChanged: _noop,
|
||||
),
|
||||
size: Size(Breakpoints.medium - 1, 800),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.text('2 / 5'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
void _noop(int _) {}
|
||||
|
||||
Reference in New Issue
Block a user