Commit Graph
3036 Commits
Author SHA1 Message Date
ajnart ecc1009e23 feat: add fixed board scaling 2026-09-08 12:37:51 +02:00
Thomas 9d857377c1 fix: refine release v2 interactions (#6805) 2026-09-08 11:36:19 +02:00
Thomas 923905c529 fix: keep bookmark density consistent (#6804)
* fix: keep bookmark density consistent

* fix: prioritize bookmark titles in compact rows

* fix: preserve compact bookmark text fallback
2026-09-08 10:39:41 +02:00
Thomas a4a903d7c3 feat: polish release v2 experience (#6800) 2026-09-07 19:17:37 +02:00
Thomas 925b0fb801 fix: improve bookmark widget density (#6802)
* fix: improve bookmark widget density

* fix: render dense bookmark grids as icons

* fix: honor bookmark column density
2026-09-07 13:47:11 +02:00
Thomas 724dee55c5 fix(weather): handle disabled external connections (#6780) 2026-09-06 15:35:06 +02:00
Thomasandajnart ca7be8f3ad fix(integrations): support UniFi controller default ports (#6787)
* fix(integrations): use Unifi default port 8443 when no port is given

The node-unifi library hardcodes https:// in its base URL and the
Unifi controller API only speaks HTTPS. When a user adds the
integration with a bare http:// or https:// URL, getPortFromUrl
returned 80 or 443, and the library attempted a TLS handshake on
the wrong port. The server's plain HTTP response caused
'EPROTO ... wrong version number'.

Derive the port from the user's explicit port, or fall back to 8443
(the integration's defaultPort). Closes #6207.

* style: auto-fix lint and format

* fix(integrations): support UniFi controller default ports

* docs(unifi): resolve review leftovers

---------

Co-authored-by: ajnart <ajnart@users.noreply.github.com>
2026-09-06 15:32:45 +02:00
134ef48848 fix(integrations): preserve Nextcloud subpaths (#6786)
* fix(integrations): preserve Nextcloud subpaths

* Keep existing Nextcloud DAV endpoints intact

---------

Co-authored-by: Artur <145776561+arturict@users.noreply.github.com>
Co-authored-by: arturict <arturict@users.noreply.github.com>
2026-09-06 15:32:37 +02:00
98aa6f01f2 feat(auth): support nested OIDC claim paths (#6785)
* feat(auth): support nested OIDC claim paths

* test(auth): cover OIDC profile name fallbacks

* test(auth): cover missing OIDC username fallback

* test(auth): preserve OIDC provider guard

---------

Co-authored-by: Artur <145776561+arturict@users.noreply.github.com>
Co-authored-by: arturict <arturict@users.noreply.github.com>
2026-09-06 15:32:31 +02:00
Thomas 4c88030b0f fix(downloads): preserve name column width (#6784) 2026-09-06 15:32:25 +02:00
Thomas 96a6926b2b fix(docker): normalize container CPU usage (#6782) 2026-09-06 15:32:15 +02:00
Thomas f89487231f fix(unraid): use byte-based memory metrics (#6781) 2026-09-06 15:32:09 +02:00
Thomas 28e242417d fix(backup): prompt re-login after restore (#6778) 2026-09-06 15:31:51 +02:00
Thomas 35155b18b9 feat: adopt Mantine 9.6 components (#6758) 2026-09-03 18:21:51 +02:00
Bergasha ac62e5bfd6 fix(system-resources): divide chart rows evenly via CSS, no board-zoom pixel math (#6756)
Each visible chart row was hardcoded to a fixed pixel height (110px in
advanced mode, 56px-capped in compact) regardless of the widget's actual
tile size - resizing the tile taller left the extra height unused, and
some visible charts required scrolling to reach.

Divide the available height evenly across rows using CSS Grid's
grid-auto-rows: 1fr (the Stack fills the tile via a definite pixel
height, the SimpleGrid grows into it via flex and divides its rows
evenly) rather than computing a per-chart pixel height in JS. Confirmed
via live inspection of a deployed board that Mantine's h prop is not
safe for this: its rem() converter strips a "px" suffix from any string
before checking whether it's a parseable number, so even a literal pixel
*string* passed through h= gets rescaled by rem() * var(--mantine-scale)
exactly like a raw number would - style.height is the only way to set
an exact, un-rescaled pixel value.
2026-09-01 16:50:00 +10:00
Thomas f57a660088 feat: add global server custom CSS (#6753)
* feat: add global server custom CSS

* refactor: reuse CodeMirror for CSS editors
2026-08-31 14:26:58 +02:00
Thomas 5e23659d99 feat(assistant): optimize MCP and custom widget authoring (#6743)
* feat(assistant): optimize MCP and custom widget authoring

* fix(assistant): isolate server-safe JSX analyzer

* refactor(assistant): generate MCP tool staging

* fix(assistant): preserve widget placement follow-up

* fix(ci): allow fast gate to finish

* fix(custom-widgets): address review findings

* fix(custom-widgets): split preview evidence module

* style: format assistant custom widget files

* fix(custom-widgets): sync formatted skill schema
2026-08-30 23:43:29 +02:00
Thomas 38f4b0e1f8 feat!: prepare Homarr v2 release (#6746) 2026-08-30 22:54:33 +02:00
Thomas 90c7493f15 fix: make bookmark compact grid actually compact (#6747) 2026-08-30 21:37:37 +02:00
Thomas 8d8dec5749 feat(widgets): consolidate integration metadata + shared response caching (#6691) 2026-08-30 18:38:07 +02:00
Bergasha 7d1d9062ed fix(calendar): keep date numbers aligned regardless of indicator dots (#6742) 2026-08-29 09:14:53 +02:00
Thomas 8d0b13b309 fix(board): correct widget scaling and edit layering (#6741) 2026-08-29 09:12:16 +02:00
Bergasha ea250d418d Revert "feat(header): add opt-in auto-hide-on-scroll for the header (#6738)" (#6740)
This reverts commit e58c229664.
2026-08-29 15:19:20 +10:00
Bergasha e58c229664 feat(header): add opt-in auto-hide-on-scroll for the header (#6738)
* feat(header): add opt-in auto-hide-on-scroll for the header

New per-user header preference (default off): when enabled, the
header slides away while scrolling down and reappears on scroll-up or
near the top of the page. Disabled while in board edit mode, and
skipped entirely while focus is inside the header. Only applies when
the header is set to visible - the existing hover-to-reveal floating
controls already cover the hidden-header case.

* chore(api): regenerate the checked-in OpenAPI schema

check:openapi was failing in CI - the schema on disk hadn't been
regenerated after the header preferences gained autoHideOnScroll.

Add scripts/generate-openapi-schema.mts (and a generate:openapi
package script) alongside the existing check script so this is a
one-command fix next time the schema drifts.

* docs(users): document the header studio's visibility and auto-hide options

Header customization (drag-to-arrange controls, hide/show, hover-reveal
and pin, auto-hide-on-scroll) had no documentation on the user general
settings page.
2026-08-29 14:56:02 +10:00
Thomas ee08beef59 fix(widgets): use readable onboarding sizes (#6739) 2026-08-29 06:55:31 +02:00
Bergasha 10ba298233 fix(board): beszel & calendar scale fix (#6737)
* fix(calendar): add cell spacing and scale day content with widget size

* fix(beszel): stop chart panels from leaving blank grid columns and size charts to fit the widget

* fix(widgets): address CodeRabbit review on calendar/beszel scaling PR

- beszel: account for the SimpleGrid row gap and the Stack gap between
  the controls row and the grid in the available-height budget, so a
  two-row layout no longer overflows the widget.
- calendar: memoize the day-cell scale lookup instead of recomputing
  it on every render.
- calendar: don't render the notification indicator row when none of
  a day's events have an indicatorColor, which was shifting the date
  number up with no visible dot to show for it.

Skipped one finding: the claim that .day's absolute inset:0 covers
monthCell's padding. It doesn't - the containing block for an
absolutely positioned element is the padding edge of its positioned
ancestor per the CSS spec, so the padding correctly insets .day. This
was also visually verified in the browser while building the fix.

* fix(beszel): don't treat availableHeight=0 as omitted in computeChartHeight

A falsy check on availableHeight also caught the legitimate value 0
(widget shorter than its own padding+controls), falling back to the
full 180px height instead of clamping to MIN_CHART_HEIGHT - the exact
overflow this height budget was meant to prevent.
2026-08-29 11:02:10 +10:00
Thomas aa179f1ec0 fix: decouple responsive layout roles from breakpoints
* fix: rework responsive layout breakpoints

* fix: keep widget edit overlays visible

* fix: inset widget edit action

* fix: use valid widget inset token
2026-08-28 17:11:51 +02:00
Thomas f221a5b4d3 fix: respect mobile header and widget interactions (#6730) 2026-08-28 08:31:41 +02:00
Bergasha c18fa8cf77 fix(widgets): replace system-resources chart tooltip with Mantine (#6729)
* fix(widgets): replace system-resources chart tooltip with Mantine Tooltip.Floating
2026-08-28 15:08:22 +10:00
Bergasha a7aa89fafe feat(board+clock): fix item radius zoom, add clock day/night weather colour (#6726) 2026-08-28 10:22:48 +10:00
Thomas 7da2e10064 fix: address release v2 review findings (#6708) 2026-08-27 13:59:42 +02:00
Thomas a002b91add feat: reduce disruptive UI confirmations (#6688)
* feat: reduce disruptive UI confirmations

* fix: keep destructive confirmations red
2026-08-27 12:01:36 +02:00
Thomas 9c441571bc fix: improve mobile header and board menus (#6715)
* fix: improve mobile header and board menus

* fix: keep mobile header logo condensed

* refactor: share mobile breakpoint handling
2026-08-27 11:08:27 +02:00
Thomas 643ecf3df7 fix(widgets): restore compact v1 surfaces (#6710) 2026-08-27 11:08:17 +02:00
Bergasha 73de83b48f Address CodeRabbit review on system resources widget PR
- Render the chart tooltip via a portal so it isn't clipped by the
  card's overflow:hidden (needed to stop the chart line itself
  bleeding past its rounded corners).
- Move chartColumns' width breakpoints into a lookup table and
  memoize the computed value, instead of an inline ternary.
2026-08-27 10:46:04 +10:00
Bergasha 26d12d9fad Fix system resources widget overflow and initial chart flicker
The chart card and its outer widget shell both had overflow:visible,
letting chart lines bleed past their rounded borders into neighboring
widgets. Compact-mode charts also stretched to fill the widget's full
resized height instead of staying compact like other widgets.

Additionally, the history used to build the chart needs 2+ points to
render a line - it started empty and only got its first real point on
the next poll (up to 30s later), so the chart would flash between a
single-value fallback and the actual graph. Both the initial render
and the first state update now seed with the current value duplicated,
so a flat line renders immediately with no flicker.
2026-08-27 09:07:05 +10:00
Thomas b2c72d54c2 fix: refine configurable header defaults (#6707) 2026-08-26 14:29:51 +02:00
Thomas a56ec5d06a feat: support every widget in the demo dashboard (#6696) 2026-08-26 08:44:55 +02:00
Bergasha 40e34181e7 fix(board-v2): icon and tiny text fix (#6704) 2026-08-26 08:44:36 +02:00
Thomas 3ee9b4f0c4 feat(custom-widgets): harden AI authoring (credential redaction, JSX policy) (#6700) 2026-08-25 17:11:24 +02:00
Thomas 9303dbd284 feat: add configurable headers and instance branding (#6690) 2026-08-25 17:09:47 +02:00
Thomas 97d8390b20 feat: rebuild command menu (#6692) 2026-08-24 15:40:09 +02:00
Thomas c9a48fa23f fix: polish login backdrop and wordmark (#6687) 2026-08-24 12:26:19 +02:00
Thomas e7c8e2e01e refactor(custom-widgets): simplify authoring prompt (#6695) 2026-08-24 09:24:53 +02:00
Thomas fcca57ddf7 feat(custom-widgets): improve authoring workbench (#6689)
* feat(custom-widgets): improve authoring workbench

* fix(custom-widgets): address review and CI

* refactor(custom-widgets): satisfy architecture checks

* fix(custom-widgets): isolate workbench typing updates

* fix(custom-widgets): harden workbench state
2026-08-24 08:55:00 +02:00
Bergasha b8bc304c5c fix(mediaServer): use proportional column widths, populate Emby playback/transcoding metadata
The User and Status columns used hardcoded pixel widths with table-layout:
fixed, so they stayed narrow regardless of how wide the widget actually
rendered - text truncated even with plenty of unused space in the
"currently playing" column. Switch both to percentages so they scale with
the widget.

Emby's integration also hardcoded playback/metadata to null for every
session, so the widget's existing progress bar, resolution, and bitrate
display never had anything to show. Port the same TranscodingInfo/
MediaStreams parsing Jellyfin already does (same underlying /Sessions API
shape) so Emby sessions get real position/duration, resolution, bitrate,
and transcode-status data. Also fix ticksToMs treating a position of
exactly 0 as missing, and share the one implementation between the two
integrations instead of duplicating it.
2026-08-24 11:16:20 +10:00
Thomas ec295fe26e Merge pull request #6684 from homarr-labs/feat/integration-card-header
fix(ui): prevent integration card title wrapping
2026-08-23 14:14:57 +02:00
ajnart e56112cfd7 fix(ui): prevent integration card title wrapping 2026-08-23 09:21:48 +02:00
Thomas Camlong 240397e7ac refactor: drop server-seeded widget clock
The WidgetTimeProvider plumbed a server timestamp and the container's
timezone down to useWidgetNow so clock widgets would paint a real time in
the SSR HTML instead of "--:--". That traded a cosmetic first-paint win for
a wrong clock: the seeded timezone is the server's, so anyone whose timezone
differs from the container's saw an incorrect time for the whole hydration
window. Fixing that properly needs a client-set timezone cookie read during
RSC render, which is far more plumbing than the problem warrants.

Revert the clock to release/v2 behaviour ("--:--" until hydration) and drop
the provider, the @homarr/widgets/time export and their tests. The e2e clock
assertions now wait on hydration explicitly instead of the seeded paint.

Also restore the widget.beszel.getSystemStats persistence exclusion. #6289
added it deliberately to keep those large time-series payloads out of the
persisted cache, and this branch had removed it with no stated rationale.

Query-cache persistence and the background-refresh indicator are unchanged.
2026-08-23 09:00:34 +02:00
Thomas Camlong 382cffc015 test: use configured DOM environment 2026-08-23 09:00:34 +02:00