feat: System page, live Logi, dashboard icons, floating help - #56
Conversation
…g help Add an admin System page for hub power, OS/Grafana links, microinit status, and dcc-bus daemons; stream Logi from microinit; sync presence on Centralki/Makiety; add dashboard heading icons and a draggable help FAB. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This Pull Request introduces significant new features and improvements across the application. The new 'System' admin page, live microinit logs, and the floating help button are well-implemented and enhance both administrative capabilities and user experience. The refactoring of the logs section from static files to a live stream is a major functional upgrade.
| Error string `json:"error,omitempty"` | ||
| } | ||
|
|
||
| // MicroinitHandler serves admin microinit service listing, info, and log WS. |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The implementation of the MicroinitHandler for live log streaming via WebSocket is robust. The in-handler authentication for WebSocket connections is a good practice, and the inclusion of log history and a keepalive mechanism ensures a reliable and user-friendly experience.
| return s.power.ShutdownMode(mode) | ||
| } | ||
|
|
||
| // Ports probes loopback TCP ports for bigfred-os-ui (8090) and Grafana (3000). |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The addition of the Ports() method and the tcpPortOpen helper function provides a clean and effective way to check the availability of local admin UIs. This is a valuable diagnostic feature for the new System page.
| * On reconnect the buffer is cleared before applying the new history | ||
| * snapshot — avoids duplicating the last N history lines. | ||
| */ | ||
| export function useMicroinitLogStream( |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The useMicroinitLogStream hook is well-designed, handling connection states, history, live updates, and pausing effectively. Clearing the buffer on reconnect before new history arrives is a thoughtful detail that prevents duplicate log entries.
| label: t("nav.administration.systemPower"), | ||
| icon: <PowerSettingsNewIcon fontSize="small" />, | ||
| onClick: () => setSystemPowerOpen(true), | ||
| id: "system", |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The refactoring of the admin menu to include the new 'System' page and the removal of the old 'Logs' entry (now replaced by live streaming) streamlines the navigation and reflects the updated functionality. The integration of FloatingHelpButton is also a great UX addition.
| export default function SystemPowerDialog({ | ||
| open, | ||
| onClose, | ||
| presetMode, |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: Making the SystemPowerDialog more flexible with the presetMode prop is a good improvement for reusability, allowing it to be adapted for specific power actions where needed.
| }; | ||
| } | ||
|
|
||
| export default function FloatingHelpButton() { |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The FloatingHelpButton is a significant UX enhancement. The drag-and-drop functionality with proper clamping, pointer event handling, and persistence via useHelpVisibility is well-implemented, providing an intuitive way for users to access help.
| }; | ||
| } | ||
|
|
||
| export function useHelpVisibility() { |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The useHelpVisibility hook effectively manages the visibility, position, and persistence of the help button and dialog. Using localStorage for user preferences like position and disabled states is appropriate and well-handled, including error mitigation for localStorage operations.
| @@ -1,27 +1,16 @@ | |||
| { | |||
| "title": "Logs", | |||
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The complete rewrite of the diagnostics translation files to support live microinit logs instead of static file logs represents a significant functional upgrade and aligns with the new backend capabilities.
Use auth.Effective for microinit log WS (sudo admins) and close the follow connection on client disconnect. Restore dictated Polish help texts with icon slots. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
The changes introduce a new 'System' administration page, integrate live microinit logs, add dashboard icons, and implement a floating help button. The backend services for microinit control and system port probing are well-structured, including robust authentication for WebSocket streams. The frontend components and hooks effectively manage state and user interaction for these new features. The refactoring of the diagnostics page to use live microinit logs is a significant functional improvement.
| } | ||
|
|
||
| wsConn, err := websocket.Accept(w, r, &websocket.AcceptOptions{ | ||
| InsecureSkipVerify: true, |
There was a problem hiding this comment.
ℹ️ [LOW] PRIORITY:LOW: The InsecureSkipVerify: true option for websocket.Accept is used here. While this might be acceptable for internal communication with microinit where TLS might not be configured or necessary, it's generally a security-sensitive flag. Consider adding a comment to explain the rationale behind this choice, e.g., "Used for internal microinit connections where TLS is not enforced or managed by BigFred."
| // reports unavailable (tests / --no-supervisor). | ||
| func NewMicroinitControl(mgr ServiceManager) *MicroinitControl { | ||
| m, ok := mgr.(*manager) | ||
| if !ok || m == nil || m.supervisor == nil { |
There was a problem hiding this comment.
ℹ️ [LOW] PRIORITY:LOW: The NewMicroinitControl function relies on a type assertion mgr.(*manager) to access the underlying supervisor client. This creates a tight coupling between MicroinitControl and the concrete implementation of ServiceManager. While the comment explains this is intentional for the microinit-backed manager, it's a design point to be aware of for future refactoring of the ServiceManager interface or its implementations.
| gap: 1, | ||
| }} | ||
| > | ||
| <DirectionsRailwayIcon fontSize="small" color="action" aria-hidden /> |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: Adding icons to the dashboard widget headings significantly improves the visual clarity and user experience, making it easier to quickly identify sections.
| export default function SystemPowerDialog({ | ||
| open, | ||
| onClose, | ||
| presetMode, |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The addition of the presetMode prop makes the SystemPowerDialog more flexible and reusable, allowing it to be configured for specific power actions or to offer all options.
| } | ||
|
|
||
| /** Shared BigFred version table used by VersionPage and SystemPage. */ | ||
| export default function VersionCard() { |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: Extracting the version display into a reusable VersionCard component is a good practice for modularity and consistency across different admin pages.
| [], | ||
| ); | ||
|
|
||
| if (!visible || !entry) return null; |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The implementation of the draggable floating help button, including pointer event handling for dragging and click detection, and position clamping, is robust and well-executed.
| "supervisord.config": "supervisord.conf", | ||
| "redis.stdout": "stdout", | ||
| "redis.stderr": "stderr" | ||
| "title": "Logs", |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The complete rewrite of the diagnostics translations reflects a significant and positive shift from a file-based log viewer to a live-streaming service-based log viewer, aligning with the PR's goal of "live Logi."
| @@ -1,27 +1,16 @@ | |||
| { | |||
| "title": "Logs", | |||
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The complete rewrite of the diagnostics translations reflects a significant and positive shift from a file-based log viewer to a live-streaming service-based log viewer, aligning with the PR's goal of "live Logi."
| @@ -1,27 +1,16 @@ | |||
| { | |||
| "title": "Logi", | |||
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The complete rewrite of the diagnostics translations reflects a significant and positive shift from a file-based log viewer to a live-streaming service-based log viewer, aligning with the PR's goal of "live Logi."
Add MicrodnsServiceDef via EnsureInfra (like redis/alloy), seed microdns.json on first run, and expose --microdns-bin. Skip on Android; best-effort when binary is missing. Foreign OS microdns drop-ins are left alone. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
This Pull Request introduces significant new features and architectural improvements, including a new 'System' admin page, live microinit log streaming, dashboard widget icons, and a floating help system. The changes demonstrate a strong focus on enhancing diagnostics, maintainability, and user experience. The refactoring of microinit and microdns management into more modular and robust components is particularly commendable.
|
|
||
| history, err := h.fetchLogHistory(serviceID, microinitLogHistoryLines) | ||
| if err != nil { | ||
| _ = writeMicroinitWS(wsConn, ctx, microinitWSMessage{Type: "error", Error: err.Error()}) |
There was a problem hiding this comment.
ℹ️ [LOW] PRIORITY:LOW: The _ = writeMicroinitWS(...) calls ignore potential errors when writing to the WebSocket. While defer wsConn.Close() and the read goroutine provide some cleanup, explicitly checking and logging errors from writeMicroinitWS could provide better insight into WebSocket write failures, especially if the connection is already in a half-open state.
| if errors.As(err, &opErr) { | ||
| return true | ||
| } | ||
| msg := err.Error() |
There was a problem hiding this comment.
ℹ️ [LOW] PRIORITY:LOW: The isClosedConn function relies on string matching for error messages (strings.Contains(msg, "closed")). This can be brittle as error messages might change across Go versions or different network implementations. Relying more on errors.Is(err, net.ErrClosed) and specific error types (like net.OpError) is generally more robust.
| }, | ||
| onOpen: () => { | ||
| // Clear before history arrives so reconnect does not append duplicates. | ||
| setLines([]); |
There was a problem hiding this comment.
ℹ️ [LOW] PRIORITY:LOW: In onOpen, setLines([]) is called to clear previous logs before history arrives. While this prevents duplicates on reconnect, if the 'history' message is delayed or fails to arrive, the log view might appear empty for a moment before live lines or an error state is shown. This is a minor UX consideration.
|
|
||
| function defaultPosition(): HelpPosition { | ||
| if (typeof window === "undefined") return { x: 24, y: 24 }; | ||
| return { |
There was a problem hiding this comment.
ℹ️ [LOW] PRIORITY:LOW: The defaultPosition for the floating help button is calculated based on window.innerWidth and window.innerHeight. While the onResize handler in FloatingHelpButton addresses dynamic resizing, the initial placement might be less ideal if the window size changes significantly before the button is interacted with or if the localStorage value is cleared. Consider a more central or less edge-dependent initial default.
| Disable: !redisMgmt.Managed, | ||
| }, | ||
| Telemetry: telemetryCfg, | ||
| Microdns: microinit.MicrodnsConfig{ |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The refactoring to replace the direct microinit.EnsureMicrodnsConfig() call with a structured microinit.MicrodnsConfig within InfraConfig is a good architectural improvement. It centralizes configuration management and makes the system more modular and testable.
| export default function SystemPowerDialog({ | ||
| open, | ||
| onClose, | ||
| presetMode, |
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: Making the SystemPowerDialog more flexible with the presetMode prop is a good improvement. It allows the dialog to be reused in contexts where only a specific power action (shutdown or reboot) is relevant, simplifying the user interface for those cases.
| @@ -0,0 +1,96 @@ | |||
| import { | |||
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: Extracting the version display into a reusable VersionCard component is a good practice for UI modularity and reusability, especially as this information is now displayed on the new System page.
| @@ -0,0 +1,57 @@ | |||
| import { Alert, CircularProgress, Stack } from "@mui/material"; | |||
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The new DccBusProgramList and DccBusProgramRow components provide a clear and interactive interface for managing DCC bus daemon controls, which is a valuable addition to the admin UI.
| @@ -0,0 +1,143 @@ | |||
| import { useCallback, useEffect, useRef, useState } from "react"; | |||
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The implementation of a draggable floating help button with persistence for its position and visibility settings (per-route and global) is a significant enhancement to the application's user experience and accessibility.
| @@ -1,27 +1,16 @@ | |||
| { | |||
There was a problem hiding this comment.
✨ [POSITIVE] POSITIVE: The complete rewrite of the diagnostics translations reflects the shift from static file-based logs to dynamic, service-oriented live log streams from microinit. This is a necessary and positive update to align with the new backend functionality.
Summary
/admin/system) with hub reboot/shutdown, live logs link, OS UI (8090) / Grafana (3000) when ports are open, microinit service table, dcc-bus daemon controls, and BigFred version card; move power actions out of the admin menu and drop the Logi menu entry (route kept).?service=deep-links); trigger layout presence sync on Centralki and Makiety.Test plan
GET /api/v1/layouts/{id}/presencefires (network tab).?service=deep-link./admin/system.Made with Cursor