chore: release v1.5.0
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 3m12s

feat: add dynamic environment widgets

Add live weather, sun position, and forecast widgets to Front Hall dashboard,
powered by data from the Qdrant volatile collection via core-api.

New widgets:
- SunPositionWidget: Animated arc showing sun/moon position with gradient colors
- ForecastWidget: Multi-day weather outlook
- Updated WeatherWidget and AirQualityWidget to accept API data

Infrastructure:
- Environment datasource calling GET /tools/environment
- Environment provider with 5-minute auto-refresh
- Freezed models for environment data

Tests:
- 12 widget tests for environment section
- Updated existing tests with givenEnvironment() harness method

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeroen Schweitzer
2026-01-06 23:05:24 +01:00
co-authored by Claude Opus 4.5
parent ea6914b5f4
commit fffc3d5baf
14 changed files with 1469 additions and 30 deletions
@@ -34,6 +34,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -47,6 +48,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -60,6 +62,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -75,6 +78,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -88,6 +92,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -101,6 +106,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -114,6 +120,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -127,6 +134,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pump();
@@ -142,6 +150,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -155,6 +164,7 @@ void main() {
await setLargeWindowSize(tester);
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenEnvironment();
harness.givenApiError(
method: 'GET',
path: '/tools/system/stats',
@@ -179,6 +189,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -191,6 +202,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -204,6 +216,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks([]); // Empty list triggers fallback
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -219,6 +232,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks(); // Fixtures have Infrastructure, Development, Home
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -235,6 +249,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -248,6 +263,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -261,6 +277,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -273,6 +290,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();
@@ -286,6 +304,7 @@ void main() {
harness.givenAuthenticatedUser();
harness.givenQuickLinks();
harness.givenSystemStats();
harness.givenEnvironment();
await tester.pumpWidget(harness.wrap(const FrontHallPage()));
await tester.pumpAndSettle();