feat(dashboard+api): card-based dashboard, camelCase API, UTC fixes
Dashboard: new Syncfusion card layout, global stats, filters, health bars, active event display, client details, bulk restart, 15s auto-refresh, manual refresh toasts API: standardized responses to camelCase; added serializers.py and updated events endpoints Time: ensured UTC storage; frontend appends 'Z' for parsing and displays local time Docs: updated copilot-instructions.md, README.md, TECH-CHANGELOG.md Program Info: bumped to 2025.1.0-alpha.12 with user-facing changelog BREAKING: external API consumers must migrate field names from PascalCase to camelCase.
This commit is contained in:
@@ -7,7 +7,73 @@ This changelog documents technical and developer-relevant changes included in pu
|
||||
|
||||
---
|
||||
|
||||
## 2025.1.0-alpha.13 (2025-10-19)
|
||||
## 2025.1.0-alpha.12 (2025-11-27)
|
||||
- 🔄 **API Naming Convention Standardization**:
|
||||
- Created `server/serializers.py` with `dict_to_camel_case()` and `dict_to_snake_case()` utilities for consistent JSON serialization
|
||||
- Events API refactored: `GET /api/events` and `GET /api/events/<id>` now return camelCase JSON (`id`, `subject`, `startTime`, `endTime`, `type`, `groupId`, etc.) instead of PascalCase
|
||||
- Internal event dictionaries use snake_case keys, then converted to camelCase via `dict_to_camel_case()` before `jsonify()`
|
||||
- **Breaking**: External API consumers must update field names from PascalCase to camelCase
|
||||
- ⏰ **UTC Time Handling**:
|
||||
- Standardized datetime handling: Database stores timestamps in UTC (naive timestamps normalized by backend)
|
||||
- API returns ISO strings without 'Z' suffix: `"2025-11-27T20:03:00"`
|
||||
- Frontend appends 'Z' to parse as UTC and displays in user's local timezone via `toLocaleTimeString('de-DE')`
|
||||
- All time comparisons use UTC; `date.toISOString()` sends UTC back to API
|
||||
- 🖥️ **Dashboard Major Redesign**:
|
||||
- Completely redesigned dashboard with card-based layout for Raumgruppen (room groups)
|
||||
- Global statistics summary card: total infoscreens, online/offline counts, warning groups
|
||||
- Filter buttons with dynamic counts: All, Online, Offline, Warnings
|
||||
- Active event display per group: shows currently playing content with type icon, title, date ("Heute"/"Morgen"/date), and time range
|
||||
- Health visualization: color-coded progress bars showing online/offline ratio per group
|
||||
- Expandable client details: shows last alive timestamps with human-readable format ("vor X Min.", "vor X Std.", "vor X Tagen")
|
||||
- Bulk restart functionality: restart all offline clients in a group
|
||||
- Manual refresh button with toast notifications
|
||||
- 15-second auto-refresh interval
|
||||
- "Nicht zugeordnet" group always appears last in sorted list
|
||||
- 🎨 **Frontend Technical**:
|
||||
- Dashboard (`dashboard/src/dashboard.tsx`): Uses Syncfusion ButtonComponent, ToastComponent, and card CSS classes
|
||||
- Appointments page updated to map camelCase API responses to internal PascalCase for Syncfusion compatibility
|
||||
- Time formatting functions (`formatEventTime`, `formatEventDate`) handle UTC string parsing with 'Z' appending
|
||||
- TypeScript lint errors resolved: unused error variables removed, null safety checks added with optional chaining
|
||||
- 📖 **Documentation**:
|
||||
- Updated `.github/copilot-instructions.md` with comprehensive sections on:
|
||||
- API patterns: JSON serialization, datetime handling conventions
|
||||
- Frontend patterns: API response format, UTC time parsing
|
||||
- Dashboard page overview with features
|
||||
- Conventions & gotchas: datetime and JSON naming guidelines
|
||||
- Updated `README.md` with recent changes, API response format section, and dashboard page details
|
||||
|
||||
Notes for integrators:
|
||||
- **Breaking change**: All Events API endpoints now return camelCase field names. Update client code accordingly.
|
||||
- Frontend must append 'Z' to API datetime strings before parsing: `const utcStr = dateStr.endsWith('Z') ? dateStr : dateStr + 'Z'; new Date(utcStr);`
|
||||
- Use `dict_to_camel_case()` from `server/serializers.py` for any new API endpoints returning JSON
|
||||
|
||||
## 2025.1.0-alpha.11 (2025-11-05)
|
||||
- 🗃️ Data model & API:
|
||||
- Added `muted` (Boolean) to `Event` with Alembic migration; create/update and GET endpoints now accept, persist, and return `muted` alongside `autoplay`, `loop`, and `volume` for video events.
|
||||
- Video event fields consolidated: `event_media_id`, `autoplay`, `loop`, `volume`, `muted`.
|
||||
- 🔗 Streaming:
|
||||
- Added range-capable streaming endpoint: `GET /api/eventmedia/stream/<media_id>/<filename>` (supports byte-range requests 206 for seeking).
|
||||
- Scheduler: Performs a best-effort HEAD probe for video stream URLs and includes basic metadata in the emitted payload (`mime_type`, `size`, `accept_ranges`). Placeholders added for `duration`, `resolution`, `bitrate`, `qualities`, `thumbnails`, `checksum`.
|
||||
- 🖥️ Frontend/Dashboard:
|
||||
- Settings page refactored to nested tabs with controlled tab selection (`selectedItem`) to prevent sub-tab jumps.
|
||||
- Settings → Events → Videos: Added system-wide defaults with load/save via system settings keys: `video_autoplay`, `video_loop`, `video_volume`, `video_muted`.
|
||||
- Event modal (CustomEventModal): Exposes per-event video options including “Ton aus” (`muted`) and initializes all video fields from system defaults when creating new events.
|
||||
- Academic Calendar (Settings): Merged “Schulferien Import” and “Liste” into a single sub-tab “📥 Import & Liste”.
|
||||
- 📖 Documentation:
|
||||
- Updated `README.md` and `.github/copilot-instructions.md` for video payload (incl. `muted`), streaming endpoint (206), nested Settings tabs, and video defaults keys; clarified client handling of `video` payloads.
|
||||
- Updated `dashboard/public/program-info.json` (user-facing changelog) and bumped version to `2025.1.0-alpha.11` with corresponding UI/UX notes.
|
||||
|
||||
Notes for integrators:
|
||||
- Clients should parse `event_type` and handle the nested `video` payload, honoring `autoplay`, `loop`, `volume`, and `muted`. Use the streaming endpoint with HTTP Range for seeking.
|
||||
- System settings keys for video defaults: `video_autoplay`, `video_loop`, `video_volume`, `video_muted`.
|
||||
|
||||
## 2025.1.0-alpha.10 (2025-10-25)
|
||||
- No new developer-facing changes in this release.
|
||||
- UI/UX updates are documented in `dashboard/public/program-info.json`:
|
||||
- Event modal: Surfaced video options (Autoplay, Loop, Volume).
|
||||
- FileManager: Increased upload limits (Full-HD); client-side duration validation (max 10 minutes).
|
||||
|
||||
## 2025.1.0-alpha.9 (2025-10-19)
|
||||
- 🗓️ Events/API:
|
||||
- Implemented new `webuntis` event type. Event creation now resolves the URL from the system setting `supplement_table_url`; returns 400 if unset.
|
||||
- Removed obsolete `webuntis-url` settings endpoints. Use `GET/POST /api/system-settings/supplement-table` for URL and enabled state (shared for WebUntis/Vertretungsplan).
|
||||
@@ -29,7 +95,7 @@ Notes for integrators:
|
||||
- Clients should now parse `event_type` and use the corresponding nested payload (`presentation`, `website`, …). `webuntis` and `website` should be handled identically (nested `website` payload).
|
||||
|
||||
|
||||
## 2025.1.0-alpha.12 (2025-10-19)
|
||||
## 2025.1.0-alpha.8 (2025-10-18)
|
||||
- 🛠️ Backend: Seeded presentation defaults (`presentation_interval`, `presentation_page_progress`, `presentation_auto_progress`) in system settings; applied on event creation.
|
||||
- 🗃️ Data model: Added `page_progress` and `auto_progress` fields to `Event` (with Alembic migration).
|
||||
- 🗓️ Scheduler: Now publishes only currently active events per group (at "now"); clears retained topics by publishing `[]` for groups with no active events; normalizes naive timestamps and compares times in UTC; presentation payloads include `page_progress` and `auto_progress`.
|
||||
|
||||
Reference in New Issue
Block a user