feat: live table refresh via SSE; remove standalone Live Logs widget#35
feat: live table refresh via SSE; remove standalone Live Logs widget#35JESREAL1JDL7LUSTRE wants to merge 7 commits intodevelopmentfrom
Conversation
…lopment update main
…lopment merge to main
…lopment sdfasda
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR integrates Server-Sent Events (SSE) for live log updates, adds Analytics and Redacted sections, implements year-level filtering, and introduces manual entry addition and flexible export functionality. The changes enable real-time table updates while removing the standalone Live Logs widget.
- Live log streaming via SSE that automatically refreshes the Records table
- Analytics dashboard with trend visualization and college/department breakdowns
- Redacted entries view for soft-deleted records
- Year level filtering for student records
- Manual entry creation dialog with validation
- Enhanced export dialog with flexible date ranges and filters
Reviewed changes
Copilot reviewed 25 out of 29 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/hooks/useLogStream.ts | SSE hook that invalidates TanStack Query cache on new log events |
| src/pages/analytics.tsx | New analytics page with trend charts, college/department rankings |
| src/features/tableRecords/redactedTable.tsx | Table component for viewing soft-deleted entries |
| src/features/formUses/ManualAddDialog.tsx | Dialog for manually creating log entries with user creation fallback |
| src/components/header/exportDialog.tsx | Enhanced export dialog supporting multiple date ranges and filters |
| src/features/tableRecords/tableRecords.tsx | Integrates SSE live updates and page preservation logic |
| src/pages/records.tsx | Restructured to support Analytics and Redacted sections via routing |
| src/pages/editInfo.tsx | Preserves page number when navigating to/from edit view |
| src/api/entries.ts | Added yearLevel filtering and getRedactedEntries function |
| src/api/analytics.ts | New analytics API functions for trends and aggregations |
| src/components/ui/dialog.tsx | Radix UI dialog component wrapper |
| src/components/ui/chart.tsx | Recharts wrapper components for consistent chart styling |
| src/components/sidebar/sidebar.tsx | Responsive sidebar with Analytics and Redacted sections |
| src/components/header/header.tsx | Integrates Manual Add and Export dialogs |
| src/components/table/yearLevelStore.ts | Context for year level filtering state |
| src/components/layout/LayoutContext.tsx | Extended to support Analytics and Redacted sections with localStorage persistence |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| {/* Logo - shown after Year Level on mobile, hidden on desktop */} | ||
| <div className="flex justify-center my-6 block md:hidden"> | ||
| <div className="flex justify-center my-6 md:hidden"> |
There was a problem hiding this comment.
The 'block md:hidden' class combination is invalid CSS. The 'block' class is always applied, making 'md:hidden' ineffective. Remove the 'block' class to properly hide the element on medium and larger screens.
| status?: string | ||
| createdAt?: string | ||
| [key: string]: unknown | ||
| [key: string]: React.ReactNode | string | number | null | undefined |
There was a problem hiding this comment.
The type definition allows React.ReactNode which is too broad for data table values. ReactNode includes elements and fragments which could cause rendering issues when used as cell values. Consider restricting to primitive types: string | number | boolean | null | undefined.
| [key: string]: React.ReactNode | string | number | null | undefined | |
| [key: string]: string | number | boolean | null | undefined |
| } | ||
|
|
||
| // Keep the connection resilient; browser retries automatically | ||
| es.onerror = () => {} |
There was a problem hiding this comment.
The error handler is empty, silently swallowing all errors. This makes debugging SSE connection issues difficult. Consider logging errors or providing user feedback when the connection fails, especially for non-transient errors.
| es.onerror = () => {} | |
| es.onerror = (event) => { | |
| // Log the error to aid in debugging SSE connection issues without | |
| // interfering with the browser's automatic retry behavior. | |
| // eslint-disable-next-line no-console | |
| console.error('Log stream EventSource error:', event) | |
| } |
| React.useEffect(() => { | ||
| if (!enabled) return | ||
| const url = API_BASE.replace(/\/$/, '') + '/logs/stream' | ||
| const es = new EventSource(url) |
There was a problem hiding this comment.
The SSE connection doesn't handle authentication. If the API requires authentication, the connection will fail. Consider adding credentials or authorization headers to the EventSource request.
| const es = new EventSource(url) | |
| const es = new EventSource(url, { withCredentials: true }) |
📝 Description
Integrates a lightweight SSE listener that invalidates TanStack Query caches when new log events arrive, causing the Records table to refresh automatically. This removes the separate “Live Logs” panel and delivers realtime updates directly in the existing table UI.
✅ Changes Made
Hook: Added useLogStream() to subscribe to /api/logs/stream and invalidateQueries(['entries']).
Integration: Enabled live refresh in src/features/tableRecords/tableRecords.tsx.
Cleanup: Removed the temporary Live Logs component from src/pages/analytics.tsx and its usage.
Config: SSE base uses VITE_API_BASE with a sensible http://localhost:5000/api fallback.
💬 Notes
Behavior: With the Records page open, new logs appear within ~1s of creation (scan/manual or POST /api/logs).
CORS: Ensure backend CORS_ORIGIN includes http://localhost:5173 (Vite) or your deployed origin(s).
Optional: We can add a polling fallback when Redis isn’t configured and/or a “replay N latest” fetch on connect.