* fix(immich): use thumbnail endpoint instead of original for album carousel
Switches from /api/assets/:id/original to /api/assets/:id/thumbnail to fix
HEIC image incompatibility (thumbnails are always JPEG), reduce bandwidth,
and improve loading speed.
Closes#6388
* working on immich
* Improve image proxy error handling
* fix(image-proxy): use trusted fetch response type
* docs(immich): require Asset View permission
The widget-only integrations refactor incorrectly removed the
ArchiveTeam Warrior integration entirely. It only needed to be
excluded from auto-seeding (by removing defaultUrl), not deleted.
This restores the integration class, reverts the widget/router/handler
to use integration middleware, and removes archiveTeamWarrior from the
widget-only-integrations migration.
* fix(beszel): harden cache layer and prevent blank widgets
- Add debug logging across Beszel integration, request handler, and tRPC
router (auth, fetch, SSE, per-procedure entry/exit) gated behind
LOG_LEVEL=debug
- cached-request-handler: retry with backoff, isValid predicate to skip
caching invalid data, in-flight dedup (single-flight per channel) to
avoid thundering herd after cache invalidation
- redis channel: set-then-publish so storage is always consistent even
when pubsub publish fails
- Beszel handlers: opt into fallbackToStaleOnError and retry so brief
upstream hiccups don't throw away good cached data
- beszel-system-stats: add refetchInterval matching each time period's
cache TTL so historical charts refresh in the background
- tRPC router: switch Promise.all -> Promise.allSettled for getSystems
and getAlerts; getSystemStats returns an error object instead of
throwing. Each result carries an optional error field so one failed
integration no longer nukes the whole widget
- Widgets: add explicit isPending loader, empty state for grid and
stats, and a shared per-integration error indicator (tooltip with
failed integration names). Alerts and table now only show their
empty state after loading completes
- Translation: add empty.noSystems key to beszelSystemGrid and
beszelSystemStats
Addresses #6030
* style: auto-fix lint and format
---------
Co-authored-by: ajnart <ajnart@users.noreply.github.com>
- Remove ternary operators from new code (widget-integration-select,
TabsContainer, mock data, members page)
- Remove stale /docs/management/tools/backup from sitemap type
- Add value prop to error-state Select in beszel-system-stats
* feat(integrations): add Gotify notifications integration
Closes#4186
> "It would be really useful if Homarr could integrate with Gotify —
> view notifications from Gotify right inside the Homarr dashboard,
> maybe as a widget or a small panel. A widget that displays the latest
> messages from Gotify (with title, message, time)."
> — #4186: feat: Gotify Integration - display notifications in Homarr
- `gotify/gotify-schema.ts` — Zod schema validating the `GET /message`
API response from the Gotify server, including id, date, title,
message body, and optional priority fields.
- `gotify/gotify-integration.ts` — `GotifyIntegration` class extending
the base `Integration` and implementing `INotificationsIntegration`.
Authenticates via HTTP Basic Auth (username + password) and fetches
the latest 100 messages from the `/message` endpoint. Connection
testing hits `/health`.
- `index.ts` — exports `GotifyIntegration` from the package public API.
- `base/creator.ts` — registers `GotifyIntegration` in the integration
creator map so it can be instantiated at runtime.
- `integration.ts` — registers the `gotify` integration definition with:
- `secretKinds: [["username", "password"]]` (Basic Auth credentials)
- `category: ["notifications"]` (picked up automatically by the
Notifications widget via `getIntegrationKindsByCategory`)
- Icon sourced from `homarr-labs/dashboard-icons`
- Documentation URL pointing to `/docs/integrations/gotify`
- `docs/homarr-docs-sitemap.ts` — adds `/docs/integrations/gotify` to
the `HomarrDocumentationPath` union type so the documentation link
passes the TypeScript path validation check.
Because `gotify` is registered under the `notifications` category, the
existing Notifications widget automatically supports it with no widget
code changes required. Users add the integration via Settings →
Integrations, supply their Gotify server URL, username, and password,
then attach it to a Notifications widget on any board.
* refactor(integrations): inline json parse and add error handling in Gotify integration
Address PR review feedback: remove intermediate `as unknown` cast by inlining
response.json() directly, and use safeParseAsync to handle deserialization
failures gracefully instead of throwing unhandled.
On macOS (and some Glances configurations) the /api/4/all endpoint
omits the quicklook key, causing a Zod invalid_type error and crashing
the system health widget. Mark quicklook as .optional() in allSchema
and add a null-safe fallback (`?? "Unknown"`) for cpuModelName.
Fixes#5728
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Consolidate 5 stat mapper useCallbacks and 6 series useMemos into
single mappers/series objects. Extract statsWhenShown helper for
repeated visibility guard pattern. Deduplicate SSE record envelope
construction. Simplify prepareRecords with if/else. Remove unused
gridColumns ternary with Number() indexing.
Replace all ternary operators with if/else, &&/||, or early returns.
Remove unused noAnimation constant that caused lint error.
Fix variable shadowing in tooltip deduplication loop.
- Surface subscription errors in useLiveStats via onError + error state
- Show error UI in live mode when SSE connection fails
- Abort SSE reader on subscribeTopic failure instead of silent log
- Guard mock realtime against pre-aborted signal to prevent interval leak
- Remove dead includeDocker from subscription input schema
- Skip toReversed() for live data (already chronological from buffer)
- Reset live buffer on systemId/integration change to avoid stale data
- Throw on unexpected SSE stream end so subscription emits error
- Delete unused time-period.ts config (duplicate of server-side config)
- Add subscribeSystemStats tRPC subscription bridging PocketBase SSE
- Add subscribeRealtimeMetrics to BeszelIntegration with SSE parsing
- Add error handling: try/catch in subscription, response check in topic POST
- Add cacheDurationForInput to request handler for per-period cache TTL
- Add mock subscribeRealtimeMetrics with 1s interval for dev testing
* chore(integrations): add ws dependency for the truenas client
* feat(definitions): allow api key authentication for truenas
* fix(integrations): connect to truenas over trusted-certificate websocket with protocol autodetection
* test(integrations): cover truenas protocol detection and authentication
* refactor(integrations): avoid shorthand index variable in truenas mapping
* feat(integrations): add a websocket url helper to the integration base
* refactor(integrations): extract truenas connection handling into a client