Build Export History List UI — List Items and Pagination
epic-bufdir-reporting-export-ui-task-010 — Implement the BufdirExportHistoryList screen with a paginated ListView.builder rendering ExportHistoryListItem widgets. Each item shows reporting period, export format badge, status chip (completed/failed), timestamp, and a Re-download icon button. Implement pull-to-refresh and infinite scroll pagination driven by the Riverpod provider. Empty state must display a helpful illustration and call-to-action.
Acceptance Criteria
Technical Requirements
Execution Context
Tier 1 - 540 tasks
Can start after Tier 0 completes
Implementation Notes
Use ConsumerWidget with ref.watch(exportHistoryProvider) to drive the list. Implement infinite scroll via ScrollController: attach a listener that checks `controller.position.pixels >= controller.position.maxScrollExtent - threshold` and calls loadNextPage only when hasMore is true and no load is in progress. Use a ValueNotifier
Format timestamps using the intl package with a locale-aware DateFormat. Status chip colours must use the app's design token system, not hardcoded hex values.
Testing Requirements
Write widget tests with flutter_test covering: (1) list renders correct number of ExportHistoryListItem widgets from mocked provider data, (2) each item displays correct period, format, status, and timestamp, (3) Re-download button is disabled for failed items and enabled for completed items, (4) scroll to near-end triggers loadNextPage, (5) pull-to-refresh calls refresh(), (6) empty state renders when provider returns empty list, (7) error state renders with retry button. Mock Riverpod provider using ProviderScope overrides with a fake ExportHistoryNotifier. Include a golden test for ExportHistoryListItem in completed and failed states.
For large exports that run for 10–30 seconds, a static loading spinner will feel broken to users on slow mobile connections. If the UI cannot display meaningful progress during the export pipeline, coordinators may abandon the flow or trigger duplicate exports by pressing the button multiple times.
Mitigation & Contingency
Mitigation: Implement streaming progress events from the orchestrator BLoC through named pipeline stages (querying, mapping, generating, uploading). Display each stage label with a progress indicator on the trigger screen. Disable the generate button immediately on first tap to prevent duplicates.
Contingency: If streaming pipeline progress is not feasible in the first release, implement a deterministic stage-based progress animation (10% querying, 50% generating, 90% uploading) that gives users feedback without requiring real server events.
Custom date range pickers are among the most common accessibility failures in mobile apps. Blindeforbundet users rely on VoiceOver, and NHF users include people with cognitive impairments. A non-accessible period picker could make the entire export workflow unusable for a significant portion of the intended user base.
Mitigation & Contingency
Mitigation: Build the period picker using Flutter's native date picker semantics as the foundation, with preset shortcuts as primary navigation (reducing the need to interact with the custom range picker at all). Test with VoiceOver on iOS and TalkBack on Android before UI epic sign-off. Engage Blindeforbundet's test contact for accessibility validation.
Contingency: If the custom date range picker cannot be made fully accessible before release, ship only the preset period shortcuts (covering the majority of use cases) and add the custom range picker in a follow-up sprint after dedicated accessibility remediation.