mirror of
https://github.com/rzuasti/oott.git
synced 2026-07-08 19:21:54 +02:00
Use server-side date filtering for device event history chart
The device event history chart previously fetched all events and filtered
client-side. This wires the existing created_from API parameter to the
frontend so filtering happens in the backend.
Also fixes a bug where the Today filter returned no results: rusqlite was
storing datetimes with a space separator ("YYYY-MM-DD HH:MM:SS+00:00")
while SQL filters used RFC 3339 with a T separator, causing string
comparisons to fail for same-day events. All datetime storage across
device_events, devices, and notifications is now consistently RFC 3339.
A migration converts existing records.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
2e8604a354
commit
e1287e5a0f
@@ -70,7 +70,7 @@ class DeviceEventHistory extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _DeviceEventHistoryState extends State<DeviceEventHistory> {
|
||||
List<DeviceEvent>? _allEvents;
|
||||
List<DeviceEvent>? _events;
|
||||
bool _isLoading = true;
|
||||
String? _error;
|
||||
_TimeRange _selectedRange = _TimeRange.lastWeek;
|
||||
@@ -89,10 +89,11 @@ class _DeviceEventHistoryState extends State<DeviceEventHistory> {
|
||||
try {
|
||||
final events = await BackendAPI.instance.getDeviceEvents(
|
||||
widget.device.macAddress,
|
||||
createdFrom: _selectedRange.cutoff,
|
||||
);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_allEvents = events;
|
||||
_events = events;
|
||||
_isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
@@ -104,12 +105,6 @@ class _DeviceEventHistoryState extends State<DeviceEventHistory> {
|
||||
}
|
||||
}
|
||||
|
||||
List<DeviceEvent> get _filteredEvents {
|
||||
if (_allEvents == null) return [];
|
||||
final cutoff = _selectedRange.cutoff;
|
||||
return _allEvents!.where((e) => e.createdOn.isAfter(cutoff)).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_isLoading) {
|
||||
@@ -126,7 +121,7 @@ class _DeviceEventHistoryState extends State<DeviceEventHistory> {
|
||||
);
|
||||
}
|
||||
|
||||
final events = _filteredEvents;
|
||||
final events = _events ?? [];
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -143,6 +138,7 @@ class _DeviceEventHistoryState extends State<DeviceEventHistory> {
|
||||
selected: {_selectedRange},
|
||||
onSelectionChanged: (selection) {
|
||||
setState(() => _selectedRange = selection.first);
|
||||
_loadEvents();
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
@@ -137,9 +137,19 @@ class BackendAPI {
|
||||
await _dio.delete('/devices/$macAddress');
|
||||
}
|
||||
|
||||
Future<List<DeviceEvent>> getDeviceEvents(String macAddress) async {
|
||||
Future<List<DeviceEvent>> getDeviceEvents(
|
||||
String macAddress, {
|
||||
DateTime? createdFrom,
|
||||
}) async {
|
||||
debugPrint('About to call GET /devices/$macAddress/events');
|
||||
final response = await _dio.get('/devices/$macAddress/events');
|
||||
final queryParams = <String, dynamic>{};
|
||||
if (createdFrom != null) {
|
||||
queryParams['created_from'] = createdFrom.toUtc().toIso8601String();
|
||||
}
|
||||
final response = await _dio.get(
|
||||
'/devices/$macAddress/events',
|
||||
queryParameters: queryParams.isEmpty ? null : queryParams,
|
||||
);
|
||||
debugPrint('Received: ${response.data}');
|
||||
return (response.data as List)
|
||||
.map((item) => DeviceEvent.fromJson(item as Map<String, dynamic>))
|
||||
|
||||
Reference in New Issue
Block a user