mirror of
https://github.com/bunny-lab-io/Borealis.git
synced 2025-12-16 15:25:48 -07:00
4.5 KiB
4.5 KiB
Codex Guide: Toast Notifications (Borealis WebUI)
Use this guide to add, configure, and test transient toast notifications across Borealis. It documents the backend endpoint, frontend listener, payload contract, and quick Firefox console commands you can hand to operators for validation.
Components & Paths
- Backend endpoint:
Data/Engine/services/API/notifications/management.py(registered as/api/notifications/notify). - Frontend listener + renderer:
Data/Engine/web-interface/src/Notifications.jsx(mounted inApp.jsx). - Transport: Socket.IO event
borealis_notificationbroadcast to connected WebUI clients.
Backend Behavior
- Auth: Uses
RequestAuthContext.require_user(); session/Bearer must be present. Returns401/403otherwise. - Route:
POST /api/notifications/notify- Emits
borealis_notificationover Socket.IO (no persistence). - Logs via
service_log("notifications", ...).
- Emits
- Validation: Requires
messagein payload.titledefaults to"Notification"if omitted. - Registration: API group
notificationsis enabled by default viaDEFAULT_API_GROUPSand_GROUP_REGISTRARSinData/Engine/services/API/__init__.py.
Payload Schema
Send JSON body (session-authenticated):
title(string, optional): Heading line. Default"Notification".message(string, required): Body copy.icon(string, optional): Material icon name hint (e.g.,info,filter,schedule,warning,error). Falls back toNotificationsActive.variant(string, optional): Visual theme. Accepted:info|warning|error(case-insensitive). Aliases:typeorseverity. Defaults toinfo.ttl_ms(number, optional): Client-side lifetime in milliseconds; defaults to ~5200ms before fade-out.
Notes:
- Payload is fanned out verbatim to the WebUI (plus server-added fields:
id,username,role,created_at). - The client caps the visible stack to the 5 most recent items (newest on top).
- Non-empty
messageis mandatory; otherwise HTTP 400.
Frontend Rendering Rules
- Component:
Notifications.jsxlistens toborealis_notificationonwindow.BorealisSocket. - Stack position: fixed top-right, high z-index, pointer events enabled on toasts only.
- Auto-dismiss: ~5s default; each item fades out and is removed.
- Theme by
variant:info(default): Borealis blue aurora gradient.warning: Muted amber gradient.error: Deep red gradient.
- Icon: No container; uses the provided Material icon hint. Small drop shadow for legibility.
Implementation Steps (Recap)
- Backend: Ensure
/api/notifications/notifyis registered (already in repo). New services should importregister_notificationsif API groups are customized. - Emit: From any authenticated server flow, POST to
/api/notifications/notifywith the payload above. - Frontend:
App.jsxmountsNotificationsglobally; no per-page wiring needed. - Test: Use the Firefox console examples below while logged in to confirm toast rendering.
Firefox Console Examples (run while signed in)
Info (default blue):
fetch("/api/notifications/notify", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: "Test Notification",
message: "Hello from the console!",
icon: "info",
variant: "info"
})
}).then(r => r.json()).then(console.log).catch(console.error);
Warning (amber):
fetch("/api/notifications/notify", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: "Heads up",
message: "This is a warning example.",
icon: "warning",
variant: "warning"
})
}).then(r => r.json()).then(console.log).catch(console.error);
Error (red):
fetch("/api/notifications/notify", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: "Error encountered",
message: "Something failed during processing.",
icon: "error",
variant: "error"
})
}).then(r => r.json()).then(console.log).catch(console.error);
Usage Notes & Tips
- Keep
messageconcise; multiline is supported via\n. - Use
iconto match the source feature (e.g.,filter,schedule,device,error). - The server adds
username/roleto payloads; the client currently shows all variants regardless of role (filtering is per-username match when present). - If sockets are unavailable, the endpoint still returns 200; toasts simply will not render until Socket.IO is connected.