Compare commits

...
Author SHA1 Message Date
Releases Homarr dbae2d2fdd chore(release): 1.19.0 [skip ci] 2025-05-02 19:15:22 +00:00
homarr-releases[bot] b9b2398cd6 chore(release): automatic release v1.19.0 2025-05-02 19:14:41 +00:00
Meier Lukas 82c5361112 feat(widget): add prefetch for apps and bookmarks (#2895) 2025-05-02 19:23:15 +02:00
homarr-renovate[bot] 2b1c433cef fix(deps): update tanstack-query monorepo to ^5.75.1 (#3006)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-05-02 12:33:30 +00:00
homarr-renovate[bot] a70b0b7047 fix(deps): update mantine monorepo to ^7.17.7 (#3004)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-05-02 09:22:12 +00:00
homarr-crowdin[bot] e148698593 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-05-02 00:51:01 +00:00
homarr-renovate[bot] 0d1b40c381 fix(deps): update tanstack-query monorepo to ^5.75.0 (#2998)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-05-01 14:19:26 +00:00
homarr-renovate[bot] a934529146 fix(deps): update testcontainers-node monorepo to ^10.25.0 (#2997)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-05-01 11:19:58 +00:00
Meier Lukas 0c9c5b8955 fix(unifi): port is ignored (#2995) 2025-05-01 12:51:20 +02:00
Meier Lukas 4dfde2ba05 refactor: remove unused pretty-print-error dependency (#2992) 2025-05-01 10:08:52 +02:00
Meier Lukas 48aef9e862 refactor: replace deprecated unsable_concat with concat for trpc middlewares (#2991) 2025-05-01 10:08:41 +02:00
Meier Lukas 547a8c34c5 fix(cookie): parsing of header not working with percentage char (#2989) 2025-05-01 10:08:29 +02:00
Meier Lukas 9006d3d2fc fix(media-request): add missing completed status (#2990) 2025-05-01 10:08:19 +02:00
homarr-crowdin[bot] a2934247b2 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-05-01 00:57:45 +00:00
homarr-renovate[bot] 1a07fa9af5 fix(deps): update dependency @t3-oss/env-nextjs to ^0.13.4 (#2993)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-30 21:21:02 +00:00
Meier Lukas ec11c738f2 chore(docs): update docs-sitemap 2025-04-30 21:06:24 +02:00
homarr-renovate[bot] 254c248e12 chore(deps): update dependency @types/react-dom to v19.1.3 (#2988)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-30 11:18:12 +00:00
homarr-renovate[bot] 70686a0066 fix(deps): update tiptap monorepo to v2.11.9 (#2987)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-30 08:45:52 +00:00
homarr-renovate[bot] 3299cedc04 fix(deps): update tanstack-query monorepo to ^5.74.11 (#2984)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-29 18:26:21 +00:00
homarr-renovate[bot] 1012cad0e3 fix(deps): update tanstack-query monorepo to ^5.74.9 (#2983)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-29 11:19:25 +00:00
homarr-renovate[bot] b10f33bf0b fix(deps): update trpc monorepo to ^11.1.2 (#2982)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-29 07:21:16 +00:00
homarr-renovate[bot] a2dbac5ad7 fix(deps): update dependency tsx to v4.19.4 (#2981)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-29 06:27:59 +00:00
Andre Silva f39a21c296 fix(releases-widget): improve ui for smaller widgets (#2962) 2025-04-28 19:04:38 +00:00
homarr-renovate[bot] 284ea239f7 fix(deps): update dependency typescript-eslint to ^8.31.1 (#2979)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-28 18:28:13 +00:00
homarr-renovate[bot] 583a6b6f4c chore(deps): update dependency @types/node to ^22.15.3 (#2978)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-28 07:47:26 +00:00
homarr-renovate[bot] 039fad643e chore(deps): update pnpm to v10.10.0 (#2976)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-28 01:13:56 +00:00
homarr-crowdin[bot] 2f2c00ba3d chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-28 00:52:47 +00:00
Meier Lukas ebb3012a65 Merge branch 'main' into dev 2025-04-27 17:24:06 +02:00
homarr-renovate[bot] f4ce76ac13 fix(deps): update tanstack-query monorepo to ^5.74.7 (#2924)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-27 15:19:19 +00:00
Releases Homarr 830660b1ef chore(release): 1.18.1 [skip ci] 2025-04-27 15:17:33 +00:00
homarr-releases[bot] f7451d182a chore(release): automatic release v1.18.1 2025-04-27 15:16:33 +00:00
Meier Lukas bb92f5bb79 fix: cannot find module http-cookie-agent/http (#2972) 2025-04-27 17:12:03 +02:00
homarr-crowdin[bot] f7ff1e3911 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-27 13:58:54 +00:00
homarr-renovate[bot] 5f80bebef2 fix(deps): update dependency mysql2 to v3.14.1 (#2969)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-27 04:22:58 +00:00
homarr-crowdin[bot] 97fe1f6a3e chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-26 00:48:49 +00:00
homarr-renovate[bot] 35fee2f380 chore(deps): update dependency @semantic-release/github to ^11.0.2 (#2956)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-25 21:20:30 +00:00
Manuel e1e26b27de docs: add 1.18.0 to issue template (#2951) 2025-04-25 19:19:14 +00:00
Releases Homarr 55cdddb274 chore(release): 1.18.0 [skip ci] 2025-04-25 19:15:32 +00:00
homarr-releases[bot] dd85f5a9d5 chore(release): automatic release v1.18.0 2025-04-25 19:14:47 +00:00
Manuel 8550c69d51 feat: migrate to unifi package (#2894) 2025-04-25 18:58:55 +00:00
3dcee8cb86 feat: add releases widget (#2497)
Co-authored-by: Andre Silva <asilva01@acuitysso.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
Co-authored-by: Manuel <30572287+manuel-rw@users.noreply.github.com>
2025-04-25 18:49:32 +00:00
homarr-renovate[bot] d97e74047d fix(deps): update turbo monorepo to ^2.5.2 (#2949)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-25 16:24:57 +00:00
homarr-renovate[bot] e36892fc8f chore(deps): update dependency @types/node to ^22.15.2 (#2946)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-25 09:22:12 +00:00
homarr-renovate[bot] 1d28bf4c93 fix(deps): update dependency drizzle-orm to ^0.43.1 (#2947)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-25 08:26:07 +00:00
homarr-renovate[bot] 8b076ce761 chore(deps): update dependency @types/node to ^22.15.1 (#2945)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-25 04:24:44 +00:00
homarr-renovate[bot] d78b2e1e85 fix(deps): update dependency tsdav to ^2.1.4 (#2944)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-25 03:09:10 +00:00
homarr-renovate[bot] f65c0125a9 chore(deps): update dependency @types/node to ^22.15.0 (#2942)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-24 21:21:27 +00:00
homarr-renovate[bot] 253308357a fix(deps): update dependency next-auth to v5.0.0-beta.27 (#2940)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-24 17:19:21 +00:00
homarr-renovate[bot] 295cc4a3c4 fix(deps): update dependency drizzle-orm to ^0.43.0 (#2939)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-24 14:20:39 +00:00
homarr-renovate[bot] 767fe946d7 fix(deps): update dependency next-intl to v4.1.0 (#2938)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-24 09:24:32 +00:00
homarr-renovate[bot] aba963c7cf fix(deps): update mantine monorepo to ^7.17.5 (#2937)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-24 09:23:37 +00:00
homarr-crowdin[bot] 4529cabb8a chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-24 04:29:49 +00:00
homarr-renovate[bot] 7766c3cbbc fix(deps): update turbo monorepo to ^2.5.1 (#2934)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-23 23:21:49 +00:00
homarr-renovate[bot] eb95ee285b fix(deps): update dependency @t3-oss/env-nextjs to ^0.13.0 (#2935)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-23 22:22:00 +00:00
homarr-renovate[bot] 1421c381cc chore(deps): update node.js to v22.15.0 (#2932)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-23 20:22:21 +02:00
homarr-renovate[bot] 573d5f89d6 fix(deps): update dependency glob to ^11.0.2 (#2931)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-23 16:24:21 +00:00
homarr-renovate[bot] e01b909402 chore(deps): update node.js to v22.15.0 (#2928)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-23 08:27:13 +00:00
homarr-renovate[bot] bd3535dcf8 fix(deps): update trpc monorepo to ^11.1.1 (#2927)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-23 01:13:29 +00:00
homarr-crowdin[bot] c4bd513134 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-23 00:50:32 +00:00
Meier Lukas c64d903f2b feat(widgets): add title to advanced options (#2909) 2025-04-22 18:33:15 +02:00
Meier Lukas f98750d0b3 feat(media-server): add option to only show playing sessions (#2899) 2025-04-22 18:30:46 +02:00
Meier Lukas c51424717d fix(certificates): improve validation and prevent crash (#2910) 2025-04-22 18:28:58 +02:00
homarr-renovate[bot] 3172e6e0c4 fix(deps): update dependency next-intl to v4.0.3 (#2922)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-22 16:25:51 +00:00
homarr-renovate[bot] 7aa379076d fix(deps): update dependency typescript-eslint to ^8.31.0 (#2919)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-22 16:25:09 +00:00
homarr-renovate[bot] 023ffcf7bf chore(deps): update dependency eslint to ^9.25.1 (#2918)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-22 01:13:02 +00:00
homarr-renovate[bot] fed28bd775 fix(deps): update dependency sass to ^1.87.0 (#2921)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-21 23:20:50 +00:00
homarr-renovate[bot] 09718b8258 chore(deps): update vitest monorepo to ^3.1.2 (#2915)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-21 09:22:24 +00:00
homarr-renovate[bot] 6040f063ca chore(deps): update pnpm to v10.9.0 (#2916)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-21 09:21:11 +00:00
homarr-renovate[bot] 3d508088d5 fix(deps): update dependency @ctrl/qbittorrent to ^9.6.0 (#2914)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-21 03:13:01 +00:00
homarr-crowdin[bot] 37484ce032 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-21 00:52:28 +00:00
Meier Lukas ac3c2a6377 chore(issue-template): add missing homarr version 1.17.0 2025-04-21 00:34:42 +02:00
homarr-renovate[bot]andMeier Lukas 6e6edc8a0d fix(deps): update dependency next-auth to v5.0.0-beta.26 (#2906)
* fix(deps): update dependency next-auth to v5.0.0-beta.26

* fix(deps): update dependency next-auth to v5.0.0-beta.26

* fix: lint issue

* fix: format issue

* fix: login with oidc no longer working

---------

Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-04-20 12:21:33 +00:00
homarr-renovate[bot] b0d7f9a48c fix(deps): update dependency @auth/core to ^0.39.0 (#2904)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-20 08:56:24 +00:00
homarr-renovate[bot] fdf700dba5 fix(deps): update dependency @auth/drizzle-adapter to ^1.9.0 (#2905)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-20 06:24:43 +00:00
homarr-renovate[bot] 2bf67c3de8 fix(deps): update dependency trpc-to-openapi to ^2.2.0 (#2903)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-19 23:19:45 +00:00
homarr-renovate[bot] 593e3ee5a6 fix(deps): update dependency dockerode to ^4.0.6 (#2901)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-19 13:03:16 +00:00
homarr-renovate[bot] ad5da4e8ac chore(deps): update dependency @vitejs/plugin-react to ^4.4.1 (#2902)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-19 12:26:25 +00:00
Releases Homarr 58ef0960b5 chore(release): 1.17.0 [skip ci] 2025-04-18 19:14:53 +00:00
homarr-releases[bot] 68d6967d24 chore(release): automatic release v1.17.0 2025-04-18 19:14:04 +00:00
homarr-renovate[bot] e5f0bb9792 chore(deps): update dependency eslint to ^9.25.0 (#2897)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-18 18:46:49 +00:00
Jacob HemmingandMeier Lukas 3d68f4d128 feat: add api-key support for tdarr (#2890)
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-04-18 20:11:51 +02:00
Jacob Hemming cfca0ba583 fix: calculate available space correctly and filter unmounted drives (#2885) 2025-04-18 10:49:59 +00:00
Meier Lukas 9570abb2c3 chore(docs): update docs-sitemap 2025-04-18 10:52:02 +02:00
homarr-renovate[bot] 5fcb7a3b9c fix(deps): update dependency recharts to ^2.15.3 (#2893)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-18 05:18:26 +00:00
homarr-crowdin[bot] a55acb9eb9 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-18 00:49:15 +00:00
homarr-renovate[bot] d37cdbd080 fix(deps): update nextjs monorepo to v15.3.1 (#2889)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-17 15:56:13 +00:00
homarr-renovate[bot] 17174b6b96 fix(deps): update tanstack-query monorepo to ^5.74.4 (#2888)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-17 09:54:31 +00:00
homarr-crowdin[bot] 0466a2808a chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-17 00:49:43 +00:00
homarr-renovate[bot] 1bfe397d68 fix(deps): update dependency zod to ^3.24.3 (#2886)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-16 22:40:20 +00:00
Meier Lukas 60de6361bb chore(docs): update docs-sitemap 2025-04-16 22:58:28 +02:00
homarr-renovate[bot] 47d7abc0d7 fix(deps): update dependency drizzle-orm to ^0.42.0 (#2882)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-16 18:51:44 +00:00
rezstjeandManuel 2d12c1e641 fix: Tdarr widget empty statistics tab (#2883)
Co-authored-by: Manuel <30572287+manuel-rw@users.noreply.github.com>
2025-04-16 18:34:06 +00:00
Thomas Camlong 00053bda7b feat: Prefer primary color (#2665) 2025-04-16 11:34:33 +02:00
homarr-renovate[bot] 97390c6030 fix(deps): update dependency drizzle-kit to ^0.31.0 (#2881)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-15 13:58:27 +00:00
homarr-renovate[bot] 865a52ae7d chore(deps): update dependency @vitejs/plugin-react to ^4.4.0 (#2879)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-15 09:40:02 +00:00
homarr-renovate[bot] fdca513929 fix(deps): update dependency typescript-eslint to ^8.30.1 (#2876)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-15 01:02:52 +00:00
homarr-crowdin[bot] ce5784b6c4 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-15 00:50:50 +00:00
homarr-renovate[bot] 1a4c136d41 chore(deps): update dependency @types/react to v19.1.2 (#2874)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-14 19:17:29 +00:00
homarr-renovate[bot] 089734b293 fix(deps): update dependency typescript-eslint to ^8.30.0 (#2873)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-14 17:37:45 +00:00
homarr-renovate[bot] 2e59bfcd60 chore(deps): update dependency @types/dockerode to ^3.3.38 (#2872)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-14 15:55:56 +00:00
homarr-renovate[bot] 02fb1b9dae fix(deps): update tanstack-query monorepo to ^5.74.3 (#2871)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-14 13:09:11 +00:00
homarr-renovate[bot] bf4a1cf1e8 fix(deps): update tanstack-query monorepo to ^5.74.2 (#2869)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-14 11:39:37 +00:00
homarr-renovate[bot] 4a0fb5d0bb chore(deps): update pnpm to v10.8.1 (#2870)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-14 11:31:01 +00:00
homarr-renovate[bot] c57b63b506 fix(deps): update dependency jotai to ^2.12.3 (#2868)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-14 01:03:30 +00:00
homarr-crowdin[bot] fa0e694ce0 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-14 00:52:46 +00:00
homarr-renovate[bot] ff1263b217 fix(deps): update dependency swagger-ui-react to ^5.21.0 (#2866)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-13 19:53:29 +00:00
homarr-renovate[bot] ac78e87042 fix(deps): update tanstack-query monorepo to ^5.74.0 (#2864)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-13 18:21:57 +00:00
homarr-renovate[bot] ec7adb03b6 chore(deps): update dependency jsdom to ^26.1.0 (#2863)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-13 10:41:29 +00:00
homarr-crowdin[bot] f5f39bc094 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-13 02:16:30 +00:00
homarr-renovate[bot] 4e6ab037c9 fix(deps): update tanstack-query monorepo to ^5.73.3 (#2860)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-12 16:18:00 +00:00
Andrea a29556ee8e fix(widget): format stock values and changes for better readability (#2836) 2025-04-12 15:53:40 +00:00
homarr-crowdin[bot] 71d8f7920d chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-12 00:48:49 +00:00
homarr-renovate[bot] 835e007334 chore(deps): update dependency @types/node to ^22.14.1 (#2857)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-11 21:43:33 +00:00
Meier Lukas d46b8f63c7 chore(issue-template): add missing homarr version 1.16.0 2025-04-11 21:56:00 +02:00
Releases Homarr a40ebb10c7 chore(release): 1.16.0 [skip ci] 2025-04-11 19:15:22 +00:00
homarr-releases[bot] 05dd6227fb chore(release): automatic release v1.16.0 2025-04-11 19:14:40 +00:00
Thomas CamlongandMeier Lukas 7a3c836a70 feat(boards): add quick app add menu item (#2681)
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-04-11 18:55:00 +00:00
Meier Lukas 4baec7e3ff fix(boards): add missing upload button for background in settings (#2853) 2025-04-11 20:17:10 +02:00
homarr-renovate[bot] 93bd09c85e chore(deps): update dependency @types/react to v19.1.1 (#2852)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-11 15:54:41 +00:00
homarr-renovate[bot] 0ed6a79a5b fix(deps): update dependency ioredis to v5.6.1 (#2851)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-11 13:08:22 +00:00
homarr-renovate[bot] 0fe4ea9dd9 fix(deps): update trpc monorepo to ^11.1.0 (#2850)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-11 12:27:29 +00:00
homarr-crowdin[bot] d6a48d132a chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-11 00:50:01 +00:00
homarr-renovate[bot] c84dd2fd79 fix(deps): update dependency dotenv to ^16.5.0 (#2848)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-10 22:39:51 +00:00
Kudou Sterain 94263c445b feat: support aria2 integration (#2226) 2025-04-10 19:40:40 +00:00
homarr-renovate[bot] 4b0b892250 fix(deps): update dependency octokit to ^4.1.3 (#2847)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-10 15:20:33 +00:00
homarr-renovate[bot] 057ff2cfc1 fix(deps): update testcontainers-node monorepo to ^10.24.2 (#2846)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-10 13:45:18 +00:00
homarr-renovate[bot] 45d285a76b fix(deps): update dependency swagger-ui-react to ^5.20.8 (#2844)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-10 11:55:51 +00:00
homarr-renovate[bot] 924a7d076e fix(deps): update dependency eslint-config-prettier to ^10.1.2 (#2842)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-10 10:58:06 +00:00
homarr-renovate[bot] f13be4a708 fix(deps): update dependency undici to v7.8.0 (#2841)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-10 10:56:42 +00:00
homarr-renovate[bot] 7fb6beceef chore(deps): update dependency proxmox-api&gt;undici to v7.8.0 (#2840)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-10 10:18:59 +00:00
homarr-renovate[bot] a1fa4297ea fix(deps): update nextjs monorepo to v15.3.0 (#2838)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-09 20:38:56 +00:00
homarr-renovate[bot] f5e3138c81 fix(deps): update tanstack-query monorepo to ^5.72.2 (#2834)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-09 14:59:53 +00:00
Meier Lukas d21755426f chore(issue-template): add missing homarr version 1.15.0 2025-04-09 16:38:50 +02:00
Releases Homarr 5b332baa75 chore(release): 1.15.0 [skip ci] 2025-04-09 13:27:11 +00:00
homarr-releases[bot] d0b9cbf155 chore(release): automatic release v1.15.0 2025-04-09 13:26:13 +00:00
Meier Lukas 3948f7f9a4 fix(security): missing authorization check for changes to notebook widget (#2832) 2025-04-09 15:24:37 +02:00
homarr-renovate[bot] 092c95bbe0 fix(deps): update testcontainers-node monorepo to ^10.24.1 (#2831)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-09 10:49:01 +00:00
homarr-renovate[bot] 0fc7ca7738 fix(deps): update nextjs monorepo to v15.2.5 (#2828)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-09 07:53:31 +00:00
homarr-renovate[bot] da34b0a3cf chore(deps): update dependency @types/react-dom to v19.1.2 (#2830)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-09 07:45:00 +00:00
homarr-renovate[bot] 75100d1a49 fix(deps): update trpc monorepo to ^11.0.4 (#2827)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-08 22:45:13 +00:00
homarr-renovate[bot] bd5dcb991c fix(deps): update mantine monorepo to ^7.17.4 (#2824)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-08 14:40:46 +00:00
homarr-renovate[bot] b064304201 fix(deps): update dependency @kubernetes/client-node to ^1.1.2 (#2825)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-08 14:18:46 +00:00
homarr-renovate[bot] c01d9a4dc5 fix(deps): update tanstack-query monorepo to ^5.72.1 (#2823)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-08 13:08:29 +00:00
homarr-renovate[bot] a821bd71f4 fix(deps): update trpc monorepo to ^11.0.3 (#2822)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-08 07:34:05 +00:00
homarr-renovate[bot] 17d92727f2 fix(deps): update dependency typescript-eslint to ^8.29.1 (#2821)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-07 17:37:29 +00:00
homarr-renovate[bot] 8ef2661be4 chore(deps): update pnpm to v10.8.0 (#2820)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-07 17:16:45 +00:00
homarr-renovate[bot] df212cf511 fix(deps): update tanstack-query monorepo to ^5.72.0 (#2817)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-07 09:38:19 +00:00
homarr-renovate[bot] 85f8d23da3 fix(deps): update dependency swagger-ui-react to ^5.20.7 (#2816)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-07 07:46:05 +00:00
homarr-renovate[bot] 275224ee68 fix(deps): update dependency ldapts to v7.4.0 (#2815)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-07 03:22:37 +00:00
homarr-crowdin[bot] ffd1005ff1 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-07 00:50:37 +00:00
Meier Lukas bf046a715c fix(medias): upload size limited by nginx to 1mb (#2813) 2025-04-06 21:33:47 +02:00
Meier Lukas c960c6fc79 chore(issue-template): add missing homarr version 1.14.0 2025-04-06 20:24:05 +02:00
Meier Lukas 75ba3f2ae7 refactor: remove central validation export to improve typescript performance (#2810)
* refactor: remove central validation export to improve typescript performance

* fix: missing package exports change in validation package

* chore: address pull request feedback
2025-04-06 10:37:28 +00:00
c1cd563048 feat: unifi controller integration (#2236)
* feat: unifi controller integration

* fix: pr feedback

* fix: pr feedback

* fix: pr feedback

* fix: formatting

* fix: pr feedback

* fix: typecheck

---------

Co-authored-by: Manuel <30572287+manuel-rw@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-04-06 10:17:51 +00:00
homarr-crowdin[bot] 7caad6fc47 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-06 00:52:20 +00:00
Meier Lukas e07b9e6a88 feat(boards): add upload buttons for background, favicon and logo (#2770)
* feat(boards): add upload buttons for background, favicon and logo

* feat(boards): use media search and show names for background

* fix: background preview not working
2025-04-05 13:54:16 +02:00
homarr-renovate[bot] 14bff5d530 chore(deps): update dependency typescript to ^5.8.3 (#2805)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-05 08:39:48 +00:00
Meier Lukas 3e88ecd64a chore(docs): update docs-sitemap 2025-04-05 10:17:53 +02:00
Meier Lukas c6102edff4 fix(performance): remove turbopack flag to no longer go out of memory after (#2803) 2025-04-04 22:30:00 +02:00
homarr-renovate[bot] 646e2c12e6 chore(deps): update dependency eslint to ^9.24.0 (#2802)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-04 19:31:51 +00:00
Releases Homarr 95e7136284 chore(release): 1.14.0 [skip ci] 2025-04-04 19:15:57 +00:00
homarr-releases[bot] 9de9aa59a4 chore(release): automatic release v1.14.0 2025-04-04 19:15:16 +00:00
homarr-renovate[bot] ee12461452 chore(deps): update dependency @types/better-sqlite3 to v7.6.13 (#2800)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-04 18:46:53 +00:00
homarr-renovate[bot] b03941ed80 fix(deps): update dependency trpc-to-openapi to ^2.1.5 (#2799)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-04 17:53:50 +00:00
homarr-renovate[bot] 968a82baf5 fix(deps): update dependency swagger-ui-react to ^5.20.6 (#2798)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-04 14:19:15 +00:00
homarr-renovate[bot] ea8bf43d7b fix(deps): update dependency @ctrl/qbittorrent to ^9.5.2 (#2795)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-04 13:34:29 +00:00
homarr-renovate[bot] 964368a06c fix(deps): update tanstack-query monorepo to ^5.71.10 (#2790)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-04 13:06:22 +00:00
homarr-renovate[bot] 98ecc683e5 fix(deps): update dependency sass to ^1.86.3 (#2796)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-04 01:01:37 +00:00
Meier Lukas 29ff879dfd fix: update check blocks page loading (#2782) 2025-04-03 23:22:50 +02:00
Meier Lukas 674253262b feat(cli): add cli command to recreate credentials admin (#2779)
* feat(cli): add cli command to recreate credentials admin

* fix: add missing username validation

* fix: deepsource issue
2025-04-03 23:22:31 +02:00
homarr-renovate[bot] f9aeb8ffe3 fix(deps): update dependency eslint-plugin-react to ^7.37.5 (#2794)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 20:21:26 +00:00
homarr-renovate[bot] 76b8b35cc1 fix(deps): update dependency @kubernetes/client-node to ^1.1.1 (#2793)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 20:18:43 +00:00
homarr-renovate[bot] 8886380f0a fix(deps): update trpc monorepo to ^11.0.2 (#2792)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 19:54:18 +00:00
homarr-renovate[bot] 0b41967ec3 fix(deps): update turbo monorepo to ^2.5.0 (#2791)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 17:19:01 +00:00
homarr-renovate[bot] 1b0504198b fix(deps): update testcontainers-node monorepo to ^10.24.0 (#2789)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 13:44:23 +00:00
homarr-renovate[bot] 3363eebddd fix(deps): update dependency swagger-ui-react to ^5.20.5 (#2787)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 11:16:57 +00:00
homarr-renovate[bot] 85672d9cf1 fix(deps): update dependency swagger-ui-react to ^5.20.4 (#2786)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 09:18:38 +00:00
homarr-renovate[bot] 3131082c77 fix(deps): update dependency sass to ^1.86.2 (#2784)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 06:59:52 +00:00
homarr-renovate[bot] f33b1cb5d0 fix(deps): update dependency recharts to ^2.15.2 (#2785)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-03 06:51:02 +00:00
homarr-renovate[bot] 4f32f11d8a chore(deps): update dependency @types/node to ^22.14.0 (#2781)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 18:58:38 +00:00
homarr-renovate[bot] 466d0e0053 fix(deps): update tanstack-query monorepo to ^5.71.5 (#2780)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 18:47:33 +00:00
Meier Lukas 7c4b71af3d chore(docs): update docs-sitemap 2025-04-02 20:19:12 +02:00
homarr-renovate[bot] 81d1231d8f fix(deps): update dependency swagger-ui-react to ^5.20.3 (#2777)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 11:32:28 +00:00
homarr-renovate[bot] 858fe6e19a fix(deps): update tanstack-query monorepo to ^5.71.3 (#2767)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 10:18:32 +00:00
homarr-renovate[bot] ff5c31342f fix(deps): update dependency undici to v7.7.0 (#2776)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 09:22:17 +00:00
homarr-renovate[bot] 807997ea76 chore(deps): update dependency proxmox-api&gt;undici to v7.7.0 (#2775)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 09:20:03 +00:00
homarr-renovate[bot] 9c12b18c6c chore(deps): update dependency @types/react-dom to v19.1.1 (#2774)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 09:18:21 +00:00
homarr-renovate[bot] 3951d052de chore(deps): update react monorepo to v19.1.0 (#2773)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 07:44:51 +00:00
homarr-renovate[bot] 5975b53212 chore(deps): update react monorepo (#2772)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 07:18:58 +00:00
homarr-renovate[bot] cc9522d981 chore(deps): update react monorepo (#2771)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-02 06:52:17 +00:00
Meier Lukas 7f77130978 fix(nextcloud): issue with self signed certificates (#2760) 2025-04-01 22:20:45 +02:00
homarr-renovate[bot] 243a97d637 chore(deps): update dependency @types/node to ^22.13.17 (#2769)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-01 17:18:29 +00:00
homarr-renovate[bot] 4feeb8b173 chore(deps): update pnpm to v10.7.1 (#2768)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-01 15:48:45 +00:00
homarr-renovate[bot] b1a8012bc7 chore(deps): update dependency @types/node to ^22.13.16 (#2766)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-01 09:56:53 +00:00
homarr-renovate[bot] 22b67188bc chore(deps): update dependency @types/node to ^22.13.15 (#2765)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-01 05:55:26 +00:00
homarr-renovate[bot] dd6e2c0f72 chore(deps): update dependency @types/ws to ^8.18.1 (#2764)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-04-01 03:40:34 +00:00
homarr-crowdin[bot] 9db0016252 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-04-01 00:56:05 +00:00
homarr-renovate[bot] 3e3505176a fix(deps): update dependency sass to ^1.86.1 (#2762)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-31 21:18:33 +00:00
homarr-renovate[bot] 3687c4b3d6 fix(deps): update dependency typescript-eslint to ^8.29.0 (#2761)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-31 17:37:16 +00:00
homarr-renovate[bot] 944010a7b1 chore(deps): update vitest monorepo to ^3.1.1 (#2758)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-31 10:43:18 +00:00
homarr-renovate[bot] db13fd03c0 fix(deps): update dependency dockerode to ^4.0.5 (#2757)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-31 09:20:46 +00:00
homarr-renovate[bot] 0b8a0098bd fix(deps): update tanstack-query monorepo to ^5.71.1 (#2756)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-31 08:51:16 +00:00
homarr-renovate[bot] 9a77b540bb chore(deps): update dependency @types/dockerode to ^3.3.37 (#2755)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-31 07:19:42 +00:00
homarr-crowdin[bot] c598579716 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-31 00:51:30 +00:00
homarr-renovate[bot] 59b1630532 fix(deps): update tiptap monorepo to v2.11.7 (#2750)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-30 15:42:50 +02:00
homarr-renovate[bot] 77044e8e0b fix(deps): update tanstack-query monorepo to ^5.71.0 (#2752)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-30 13:03:05 +00:00
homarr-renovate[bot] 0ec8f23b7c fix(deps): update tiptap monorepo to v2.11.7 (#2749)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-30 01:05:20 +00:00
homarr-renovate[bot] c69e331ded fix(deps): update dependency trpc-to-openapi to ^2.1.4 (#2748)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-30 01:04:35 +00:00
homarr-crowdin[bot] 4273cd9fcd chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-30 00:52:59 +00:00
Meier Lukas 98515312a2 revert: add restriction callback to restrict visibility and modification of widget kinds (#2746)
This reverts commit 84f73d33a0.
2025-03-29 12:43:10 +01:00
homarr-crowdin[bot] d1b14aca8b chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-29 00:47:55 +00:00
Manuel c6b4c9cbf2 docs: add 1.13.1 to issue template (#2738) 2025-03-28 22:04:23 +00:00
Releases Homarr 19029f40b8 chore(release): 1.13.1 [skip ci] 2025-03-28 21:58:28 +00:00
homarr-releases[bot] b6bc257726 chore(release): automatic release v1.13.1 2025-03-28 21:57:48 +00:00
Manuel fef50a53b1 revert: ssg integration create (#2736) 2025-03-28 21:56:45 +00:00
homarr-renovate[bot] 94ff401d7d fix(deps): update react monorepo to v19.1.0 (#2734)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 20:20:12 +00:00
Manuel 63328d125a docs: add 1.13.0 to issue template (#2733) 2025-03-28 20:29:12 +01:00
Releases Homarr 457b970d8f chore(release): 1.13.0 [skip ci] 2025-03-28 19:15:13 +00:00
homarr-releases[bot] 8d69970562 chore(release): automatic release v1.13.0 2025-03-28 19:14:18 +00:00
ManuelandMeier Lukas 8a071f9ab6 fix: bookmarks layout (#2675)
* fix: bookmarks layout

* chore: address pull request feedback

* fix: make icon bigger when only icon exists for vertical item

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-28 20:11:31 +01:00
homarr-crowdin[bot] 76b67ac8e1 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-28 17:22:17 +00:00
ManuelandMeier Lukas eba738e5d6 feat: add german swiss locale (#2726)
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-28 18:01:16 +01:00
Manuel 996ec548c4 revert: add development package and update workspace (#2700)" (#2728)
This reverts commit 7706f97228.
2025-03-28 17:00:57 +00:00
Meier Lukas 40e00987cb fix: allow deletion of external users (#2725) 2025-03-28 17:58:54 +01:00
Jack Weller 93c64baec2 feat(lang): add english uk language (#2715) 2025-03-28 16:45:13 +00:00
Meier Lukas b5b0b069d2 fix(auth): fusion auth returns www-authenticate token response (#2719)
* fix(auth): fusion auth returns www-authenticate token response

* docs: fix typo in comment

* fix: deepsource issue
2025-03-28 17:44:26 +01:00
Meier Lukas 62c7955e48 fix(import): autofix missing shapes for sidebars and some sections as well (#2723) 2025-03-28 17:44:11 +01:00
homarr-renovate[bot] 217818573e fix(deps): update trpc monorepo to ^11.0.1 (#2724)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 16:20:05 +00:00
homarr-renovate[bot] 70879ccb90 chore(deps): update dependency @types/dockerode to ^3.3.36 (#2721)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 15:30:12 +00:00
homarr-renovate[bot] 34eb9b366f fix(deps): update tanstack-query monorepo to ^5.70.0 (#2722)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 15:18:23 +00:00
homarr-renovate[bot] ac77bdd84c fix(deps): update nextjs monorepo to v15.2.4 (#2720)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 13:07:34 +00:00
Manuel 70ea093eb6 fix: calendar indicators (#2712) 2025-03-28 13:43:45 +01:00
Meier Lukas 08e0dd76ae chore(deps): update nextjs to 15.2.3 (#2701)
* chore(deps): update nextjs to 15.2.3

* fix: dev server crashes with next 15.2.0

* chore(deps): reenable updates for next packages

* chore: address pull request feedback
2025-03-28 13:39:20 +01:00
homarr-renovate[bot] 0ed4c741c5 fix(deps): update tiptap monorepo to v2.11.6 (#2718)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 12:28:38 +00:00
homarr-renovate[bot] 569ec6fe5c fix(deps): update dependency drizzle-zod to ^0.7.1 (#2717)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 12:27:33 +00:00
homarr-renovate[bot] e7e80dbc7d fix(deps): update tanstack-query monorepo to ^5.69.3 (#2716)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 11:16:27 +00:00
Andre SilvaandAndre Silva b054bdd987 refactor: icon picker add asterisk option (#2496)
* fix: added `withAsterisk` property to `IconPicker`, defaulted to true so it's backwards compatible

* fix: `icon-picker.tsx` formatting

---------

Co-authored-by: Andre Silva <asilva01@acuitysso.com>
2025-03-28 10:18:52 +01:00
Meier Lukas 84f73d33a0 feat(widget): add restriction callback to restrict visibility and modification of widget kinds (#2658)
* feat(widget): add restriction callback to restrict visibility and modification of widget kinds

* fix: typecheck issue

* chore: address pull request feedback
2025-03-28 10:16:46 +01:00
homarr-renovate[bot] 78b55202e7 fix(deps): update tanstack-query monorepo to ^5.69.2 (#2714)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-28 08:42:46 +00:00
Thomas Camlong 7706f97228 chore: add development package and update workspace (#2700)
* feat: add development package and update workspace

- Introduced a new development package with a Docker Compose script.
- Updated pnpm workspace to include the development directory.
- Changed Turbo UI setting from 'stream' to 'tui'.

* fix: rename

* Discard changes to turbo.json
2025-03-27 23:18:12 +00:00
Meier Lukas a0ee558582 chore: replace allowNonAppliedPatches with allowUnusedPatches 2025-03-27 23:45:36 +01:00
Meier Lukas 94d3dad909 feat(auth): add env variable to force user-info usage instead of idtoken (#2711) 2025-03-27 22:57:06 +01:00
Thomas Camlong 1a3a55934d feat: implement auto-select icon (#2679) 2025-03-27 22:18:11 +01:00
Manuel 8bf893b392 feat: app dropdown add infinity scroll (#2696) 2025-03-27 20:27:39 +00:00
homarr-renovate[bot] 43b8cfa4dd fix(deps): update dependency undici to v7.6.0 (#2710)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-27 14:42:06 +00:00
homarr-renovate[bot] a05b5965b6 chore(deps): update dependency proxmox-api&gt;undici to v7.6.0 (#2709)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-27 14:40:58 +00:00
homarr-renovate[bot] 68407eaa19 fix(deps): update dependency swagger-ui-react to ^5.20.2 (#2708)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-27 14:40:06 +00:00
homarr-renovate[bot] 6854e4729d fix(deps): update mantine monorepo to ^7.17.3 (#2707)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-27 10:41:42 +00:00
homarr-renovate[bot] f03e381aea fix(deps): update dependency drizzle-kit to ^0.30.6 (#2706)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-27 09:38:28 +00:00
homarr-renovate[bot] 151ccb7086 chore(deps): update dependency @types/node to ^22.13.14 (#2705)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-27 03:51:48 +00:00
Thomas Camlong 8f7f2110ec feat: set home board when creating first board (#2683)
* feat: set home board when creating first board

* refactor: move home board assignment to backend

* refactor: revert changes

* fix: add back missing run() calls
2025-03-26 23:29:34 +01:00
Meier Lukas 579dd5763d feat(logs): improve logs by logging errors with causes and metadata (#2703)
* feat(logs): improve logs by logging errors with causes and metadata

* fix: deepsource issue
2025-03-26 21:53:51 +01:00
Thomas Camlong 3e1c000d51 feat: add default search engines seeding / set homarr docs as global server search engine (#2663)
* feat: add default search engines seeding

* feat: set Homarr Docs as the default search

Set the default search engine in server settings during seeding

* refactor: use typed methods to define settings

* feat: add insertServerSettingByKeyAsync

* feat: update seeding logic for server settings

* fix: format file using prettier

* fix: disable eslint for `urlTemplate`

* refactor: remove never happning else

* feat: enhance createDocumentationLink

- Updated createDocumentationLink to accept query parameters

* test: add unit tests for createDocumentationLink

* fix: update urlTemplate for Homarr documentation
2025-03-26 21:25:13 +01:00
homarr-renovate[bot]andMeier Lukas f624611540 fix(deps): update dependency typescript-eslint to ^8.28.0 (#2693)
* fix(deps): update dependency typescript-eslint to ^8.28.0

* fix: lint issues

---------

Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-26 20:17:23 +00:00
Manuel 07f0abf28c feat: add jetbrains run profile (#2704) 2025-03-26 20:15:25 +00:00
homarr-renovate[bot] c3264b2fe1 fix(deps): update testcontainers-node monorepo to ^10.23.0 (#2699)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-26 16:22:32 +00:00
homarr-renovate[bot] d0aa48fab3 chore(deps): update pnpm to v10.7.0 (#2698)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-26 11:54:06 +00:00
Meier Lukas d634fa2c95 chore(docs): update docs-sitemap 2025-03-25 20:48:18 +01:00
Flávio Augusto Oliveira Costaandfaugusto-oliveira 5a8405a9a8 fix: Media request via search engine (#2677)
* fix search engine using season.id instead of season.seasonNumber on POST to overseerr/jellyseerr causing a incorrect request

* fix format on overseerr-integration.ts

---------

Co-authored-by: faugusto-oliveira <faugusto.oliveira@outlook.com>
2025-03-25 06:38:03 +00:00
homarr-crowdin[bot] a6f388d076 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-25 00:49:34 +00:00
Jack WellerandMeier Lukas 1dd7b1a6b9 feat: add title to dynamic section (#2614)
* feat: add title to dynamic section

* fix: formatting

* feat: use badge rather than text

* fix: use board radius

* fix: use shared.ts validation

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-24 22:06:50 +01:00
homarr-renovate[bot] b7a6d950db fix(deps): update testcontainers-node monorepo to ^10.22.0 (#2692)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-24 16:22:29 +00:00
homarr-renovate[bot] 00f5a877a6 fix(deps): update dependency ldapts to v7.3.3 (#2691)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-24 16:20:50 +00:00
homarr-renovate[bot] 75a949eecf chore(deps): update dependency @types/node to ^22.13.13 (#2689)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-24 11:17:37 +00:00
Thomas Camlong ce0705e9d4 feat: SSG integration creation page (#2684)
The new path is /new/{kind} so that it can be used in SSG
2025-03-24 10:33:30 +01:00
homarr-renovate[bot] 0f4a9af57d chore(deps): update dependency @types/node to ^22.13.12 (#2688)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-24 06:53:01 +00:00
homarr-crowdin[bot] 703a362356 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-24 00:50:13 +00:00
Thomas Camlong 826d54a0ca chore(i18n): update regex patterns for i18n-ally (#2685) 2025-03-23 21:30:15 +01:00
Thomas Camlong 46c95e0da3 feat: auto sign-in when creating the initial user (#2664)
* feat: auto sign-in on init user
2025-03-23 16:52:00 +01:00
Meier Lukas 0aacbe95c2 chore(docs): update docs-sitemap 2025-03-22 12:13:55 +01:00
homarr-crowdin[bot] 18f845b4c4 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-22 00:47:07 +00:00
homarr-renovate[bot] b5ae5f876b chore(deps): update dependency eslint to ^9.23.0 (#2672)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-21 23:18:27 +00:00
Meier Lukas ef359b6997 chore(issue-template): add missing homarr version 1.12.0 2025-03-21 20:17:09 +01:00
Releases Homarr 1d3dc5b9e7 chore(release): 1.12.0 [skip ci] 2025-03-21 19:14:56 +00:00
homarr-releases[bot] ff0b0c659c chore(release): automatic release v1.12.0 2025-03-21 19:14:11 +00:00
homarr-renovate[bot] 8dee8f8680 fix(deps): update dependency drizzle-orm to ^0.41.0 (#2666)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-21 17:45:16 +00:00
Meier Lukas 25e4c814ac chore(deps): update trpc to v11 (#2668) 2025-03-21 18:32:51 +01:00
homarr-renovate[bot] 3edfe6bfed chore(deps): update dependency @types/node to ^22.13.11 (#2662)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-21 09:19:41 +00:00
homarr-crowdin[bot] 22d32ccb8d chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-21 00:48:20 +00:00
Meier Lukas 7aa5d2f8ed chore(docs): update docs-sitemap 2025-03-20 19:58:23 +01:00
Jack WellerandMeier Lukas 91a69c162a feat: stock price widget (#2579)
* feat: added stock price widget

* fix: formatting

* fix: broken lock file

* fix: requested changes

* fix: added parsing schema

* fix: improve time range and interval inputs

* fix: only return required data

* fix: formatting

* fix: deepsource tests

* fix: moved all time frames into one location

* fix: formatting

* fix: requested changes

* fix: formatting

* fix: parse response data

* fix: update packages

* fix: typescript issues

* fix: formatting

* fix: broken lockfile

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-20 17:49:19 +01:00
homarr-renovate[bot] e3fcfbe916 fix(deps): update dependency typescript-eslint to ^8.27.0 (#2653)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-20 03:13:48 +00:00
homarr-renovate[bot] 3e4d24b28e fix(deps): update dependency mysql2 to v3.14.0 (#2652)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-20 02:25:10 +00:00
homarr-crowdin[bot] 425d5edab5 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-20 00:47:16 +00:00
Meier Lukas b0381cb883 fix(cli): fix-usernames command only fixes lowercase usernames (#2650) 2025-03-19 21:05:06 +01:00
homarr-renovate[bot] a04cb25dd0 chore(deps): update dependency @types/react to v19.0.12 (#2648)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-19 15:19:17 +00:00
homarr-renovate[bot] b4692b62ab chore(deps): update pnpm to v10.6.5 (#2647)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-19 13:49:19 +00:00
Manuel bb8cb6dded fix: prohibit dot in board name (#2643) 2025-03-19 09:26:18 +01:00
Meier Lukas 4cc37397c2 fix(permissions): unable to edit board with full board permissions (#2625) 2025-03-18 20:34:38 +01:00
homarr-renovate[bot] 2d2ae5a419 fix(deps): update tanstack-query monorepo to ^5.69.0 (#2634)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-18 11:30:40 +00:00
homarr-renovate[bot] 15197897ac fix(deps): update testcontainers-node monorepo to ^10.21.0 (#2633)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-18 10:42:19 +00:00
homarr-renovate[bot] 289c7f1a60 fix(deps): update dependency better-sqlite3 to ^11.9.1 (#2632)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-18 02:26:38 +00:00
homarr-crowdin[bot] 495432073f chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-18 00:47:24 +00:00
homarr-renovate[bot] c9fecaabb6 fix(deps): update dependency sass to ^1.86.0 (#2629)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-17 21:54:52 +00:00
homarr-renovate[bot] 5b49fe1039 chore(deps): update dependency @types/react to v19.0.11 (#2628)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-17 21:42:40 +00:00
homarr-renovate[bot] 7ba2067689 fix(deps): update dependency drizzle-orm to ^0.40.1 (#2624)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-17 14:38:14 +00:00
homarr-renovate[bot] e0ae5e6705 chore(deps): update vitest monorepo to ^3.0.9 (#2622)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-17 14:19:46 +00:00
homarr-renovate[bot] 305d259e98 chore(deps): update pnpm to v10.6.4 (#2623)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-17 14:17:43 +00:00
homarr-crowdin[bot] fed3d1ce23 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-16 00:51:24 +00:00
homarr-crowdin[bot] 8f083adf39 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-15 00:46:38 +00:00
Meier Lukas 3e9c8172ef chore(issue-template): add missing homarr version 1.11.0 2025-03-14 20:39:16 +01:00
Meier Lukas f743c76b17 chore(docs): update docs-sitemap 2025-03-14 20:36:56 +01:00
Releases Homarr 7d8650babc chore(release): 1.11.0 [skip ci] 2025-03-14 19:14:50 +00:00
homarr-releases[bot] 612f0e4fbf chore(release): automatic release v1.11.0 2025-03-14 19:14:07 +00:00
homarr-renovate[bot] 75fb9dbf1e fix(deps): update testcontainers-node monorepo to ^10.20.0 (#2602)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-14 18:22:40 +00:00
homarr-crowdin[bot] 7f7156a798 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-14 15:49:17 +00:00
ManuelandMeier Lukas 85d2d61184 fix: action icons not being rendered (#2593)
* fix: action icons not being rendered

* fix: format issue

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-14 16:40:21 +01:00
homarr-renovate[bot] 25f7406283 fix(deps): update tanstack-query monorepo to ^5.68.0 (#2600)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-14 10:18:19 +00:00
homarr-renovate[bot] 1e50ac411c fix(deps): update mantine monorepo to ^7.17.2 (#2599)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-14 08:42:06 +00:00
homarr-renovate[bot] 04c17d1c41 fix(deps): update dependency better-sqlite3 to ^11.9.0 (#2598)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-14 03:13:01 +00:00
Meier Lukas 22f9166690 feat(integrations): add checkbox to add app (#2463) 2025-03-13 23:23:54 +01:00
homarr-renovate[bot] 8a02c65648 fix(deps): update dependency @kubernetes/client-node to ^1.1.0 (#2591)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-13 15:19:00 +00:00
homarr-renovate[bot] bb20999bf3 chore(deps): update pnpm to v10.6.3 (#2590)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-13 14:37:46 +00:00
homarr-renovate[bot] b607c5702f fix(deps): update dependency next-intl to v4.0.2 (#2589)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-13 14:18:13 +00:00
homarr-crowdin[bot] 83eacb23b9 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-13 00:47:42 +00:00
homarr-renovate[bot] d8247f2dc9 fix(deps): update dependency next-intl to v4.0.1 (#2585)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-12 19:16:10 +00:00
homarr-renovate[bot] 56fe8dd9e9 fix(deps): update dependency undici to v7.5.0 (#2583)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-12 18:23:39 +00:00
homarr-renovate[bot] c94159388d chore(deps): update dependency proxmox-api&gt;undici to v7.5.0 (#2582)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-12 18:21:16 +00:00
homarr-renovate[bot]andMeier Lukas f55d8a9c2e fix(deps): update dependency next-intl to v4 (#2580)
* fix(deps): update dependency next-intl to v4

* fix: typecheck issue

* refactor: implement improvements for next-intl v4

* fix: typecheck issues

* fix: typecheck issue

---------

Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-12 18:37:43 +01:00
homarr-crowdin[bot] 47ebc66c9e chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-12 00:46:48 +00:00
homarr-renovate[bot] d669f99ac1 fix(deps): update testcontainers-node monorepo to ^10.19.0 (#2576)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-11 22:37:33 +00:00
Meier Lukas 3d4d32f377 feat(logs): improve error logs with stacked causes (#2574) 2025-03-11 22:15:13 +01:00
Meier Lukas 268daee4a6 fix(system-health): improve responsive styles (#2566) 2025-03-11 22:15:01 +01:00
Meier Lukas a53e7aaee5 fix(notebook): css for checkboxes not working (#2570) 2025-03-11 22:14:35 +01:00
Meier Lukas fbbfe9af29 fix(calendar): dropdown spans over whole screen (#2569) 2025-03-11 22:13:17 +01:00
Meier Lukas e774b06fc2 fix(dns-hole-summary): remove inconsistency for position of text (#2568) 2025-03-11 22:13:03 +01:00
homarr-renovate[bot] 6c9fbd6c09 fix(deps): update dependency zod-form-data to ^2.0.7 (#2573)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-11 20:36:28 +00:00
homarr-renovate[bot] 2135f9980b fix(deps): update dependency zod-form-data to ^2.0.6 (#2572)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-11 19:53:42 +00:00
Meier Lukas ba3f1e9eaa chore(docs): update docs-sitemap 2025-03-11 18:42:18 +01:00
homarr-renovate[bot] 8486073f27 fix(deps): update tanstack-query monorepo to ^5.67.3 (#2567)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-11 17:37:42 +00:00
dependabot[bot] afcde8afe5 chore(deps): bump prismjs from 1.27.0 to 1.30.0 (#2565)
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.27.0 to 1.30.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.27.0...v1.30.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-11 17:58:31 +01:00
homarr-renovate[bot] a102f39518 fix(deps): update dependency video.js to ^8.22.0 (#2564)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-11 13:05:22 +00:00
homarr-crowdin[bot] 225ed4881b chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-11 00:47:24 +00:00
Meier Lukas d714e53cfa fix(downloads): improve responsive styles (#2552) 2025-03-10 20:29:50 +01:00
homarr-crowdin[bot] 483ce9c28d chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-10 19:28:30 +00:00
homarr-renovate[bot] ff6ca86a78 fix(deps): update dependency jotai to ^2.12.2 (#2560)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-10 18:56:34 +00:00
homarr-renovate[bot] 55ad0b0a65 fix(deps): update dependency typescript-eslint to ^8.26.1 (#2561)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-10 18:42:17 +00:00
homarr-renovate[bot] 8cb8eaf9cc fix(deps): update dependency prismjs to ^1.30.0 (#2562)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-10 18:19:33 +00:00
homarr-renovate[bot] 9c582d906b fix(deps): update dependency swagger-ui-react to ^5.20.1 (#2558)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-10 11:13:59 +00:00
homarr-renovate[bot] d6cfd23068 chore(deps): update pnpm to v10.6.2 (#2557)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-10 02:54:31 +00:00
oussama Dahmazandoussama Dahmaz f19aa29607 feat(kubernetes): add kubernetes tool (#1929)
Co-authored-by: oussama Dahmaz <dahmaz@MacBook-Pro-de-odahmaz.local>
2025-03-09 17:46:15 +01:00
Meier Lukas f6f0d7c72b feat(calendar): add show-unmonitored option (#2547)
* feat(calendar): add show-unmonitored option

* fix: typecheck issue
2025-03-09 14:26:31 +01:00
Meier Lukas 2f80c096a7 fix(minecraft-status): wrong api path for bedrock (#2551) 2025-03-09 14:24:27 +01:00
Meier Lukas 8f8d7884a9 fix(media-transcoding): improve responsive styles (#2550)
* fix(media-transcoding): improve responsive styles

* fix: typecheck issue
2025-03-09 14:22:12 +01:00
Meier Lukas d584ade8f4 fix(media-request-stats): improve responsive styles (#2544)
* fix(media-request-stats): improve responsive styles

* fix(media-request-stats): put user to start
2025-03-09 14:20:23 +01:00
Meier Lukas 82528dbd96 fix(media-server): improve responsive styles (#2548)
* fix(media-server): improve responsive styles

* fix(media-server): translate table headers
2025-03-09 14:20:04 +01:00
homarr-crowdin[bot] d9720ac596 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-09 00:42:54 +00:00
Meier Lukas 9e48f438b4 fix(media-request-list): improve responsive styles (#2543) 2025-03-08 23:54:57 +01:00
Meier Lukas 4472c04967 fix(indexer-manager): improve responsive styles (#2541) 2025-03-08 23:46:43 +01:00
Manuel 2e62a61f4d feat: add nextcloud integration (#2501) 2025-03-08 22:13:45 +00:00
Meier Lukas 0b07f227ee fix(smart-home): improve responsive styles (#2540) 2025-03-08 20:55:25 +01:00
Meier Lukas fd5b1b0c08 fix(date-time): improve responsive styles (#2539) 2025-03-08 20:55:15 +01:00
Meier Lukas 1db9c3c692 fix(calendar): improve responsive styles (#2538)
* fix(calendar): improve responsive styles

* fix: remove temporary events

* fix: deepsource issue
2025-03-08 20:55:03 +01:00
Meier Lukas fb800a0008 fix(app): improve responsive styles (#2537) 2025-03-08 20:54:48 +01:00
Meier Lukas c0e1355d7f fix(dns-controls): improve responsive styles (#2534)
* fix(dns-controls): improve responsive styles

* fix: further dns-control improvements
2025-03-08 20:54:35 +01:00
Meier Lukas 7ec6fbc376 fix(dns-summary): improve responsive styles (#2535) 2025-03-08 20:54:24 +01:00
Meier Lukas df249a0173 fix(bookmarks): improve responsive styles (#2536)
* fix(bookmarks): improve responsive styles

* fix: typecheck issue
2025-03-08 20:54:12 +01:00
homarr-renovate[bot] ac5fc38ec0 chore(deps): update dependency @types/node to ^22.13.10 (#2533)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-08 08:36:57 +00:00
homarr-crowdin[bot] 75bee0be8b chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-08 00:38:29 +00:00
Jack WellerandMeier Lukas b3464b3340 feat(widgets): add border color option to advanced-options (#2512)
* feat: add border color option for all widgets

* fix: broken lockfile

* fix: typecheck issue

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-07 22:56:16 +01:00
homarr-renovate[bot] 4a7ccda362 chore(deps): update dependency eslint to ^9.22.0 (#2530)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-07 21:43:30 +00:00
Meier Lukas d410af3402 fix(import): autofix missing sizes of items with grid-algorithm (#2522) 2025-03-07 21:27:29 +01:00
Meier Lukas 65f00f19de chore(issue-template): add missing homarr version 1.10.0 2025-03-07 21:25:24 +01:00
homarr-renovate[bot] e3ad569cc2 chore(deps): update pnpm to v10.6.1 (#2521)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-07 19:59:18 +00:00
Releases Homarr f25837f9f8 chore(release): 1.10.0 [skip ci] 2025-03-07 19:13:59 +00:00
homarr-releases[bot] 44007b2b4b chore(release): automatic release v1.10.0 2025-03-07 19:13:16 +00:00
ManuelandMeier Lukas 37d471457a feat: remove cqmin system (#2407)
* feat: remove cqmin system

* fix: improve weather widget

---------

Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2025-03-07 18:46:01 +01:00
Meier Lukas 9881577f47 fix(pi-hole): wrong fetch used in factory (#2527) 2025-03-07 18:14:50 +01:00
homarr-renovate[bot] a572aae887 fix(deps): update tanstack-query monorepo to ^5.67.2 (#2525)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-07 11:15:49 +00:00
homarr-renovate[bot] 4721a97094 fix(deps): update dependency eslint-config-prettier to ^10.1.1 (#2524)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-07 10:19:12 +00:00
homarr-crowdin[bot] 15026afa46 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-07 00:47:20 +00:00
Meier Lukas 3403579925 chore(issue-template): add missing homarr versions until 1.9.0 2025-03-06 17:57:48 +01:00
Meier Lukas da4aaba9f0 Merge branch 'main' into dev 2025-03-06 17:54:14 +01:00
homarr-renovate[bot] 98dd96f37c chore(deps): update vitest monorepo to ^3.0.8 (#2519)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-06 15:37:30 +00:00
homarr-renovate[bot] 67c739c35b fix(deps): update dependency mysql2 to v3.13.0 (#2516)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-06 06:19:00 +00:00
homarr-crowdin[bot] 6f8b3de903 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-06 00:47:27 +00:00
homarr-renovate[bot] e4a39223a3 fix(deps): update dependency ioredis to v5.6.0 (#2509)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-05 21:33:39 +00:00
Releases Homarr 72860a877b chore(release): 1.9.0 [skip ci] 2025-03-05 19:01:09 +00:00
homarr-releases[bot] 0f3089a1bd chore(release): automatic release v1.9.0 2025-03-05 19:00:29 +00:00
homarr-crowdin[bot] 84519bf734 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-05 00:47:09 +00:00
homarr-renovate[bot] 478aae6cd4 fix(deps): update dependency @tabler/icons-react to ^3.31.0 (#2502)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-04 23:54:15 +00:00
Meier Lukas 604a05f9d5 fix: affix hides pagination on mobile (#2491) 2025-03-04 22:01:58 +01:00
Meier Lukas b3e4f30312 fix(integration): store omv session in redis (#2467)
* feat(pihole): add support for v6

* fix: add session-store to keep using same session for pi-hole requests

* fix(integration): store omv session in redis

* chore: address pull request feedback
2025-03-04 21:46:11 +01:00
Manuel a3999bcf52 fix: docker add to homarr layout overflow (#2441) 2025-03-04 21:39:38 +01:00
Meier Lukas 3804d530ec feat(pihole): add support for v6 (#2448)
* feat(pihole): add support for v6

* fix: add session-store to keep using same session for pi-hole requests

* chore: address pull request feedback

* fix: import issue

* fix: other import errors
2025-03-04 21:17:35 +01:00
homarr-renovate[bot] e88b29dc9d chore(deps): update dependency @types/ws to ^8.18.0 (#2499)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-04 19:14:45 +00:00
homarr-crowdin[bot] d470ea4ede chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-04 00:47:03 +00:00
homarr-renovate[bot] 21f3a5a408 fix(deps): update dependency typescript-eslint to ^8.26.0 (#2488)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-03 18:42:27 +00:00
homarr-renovate[bot] 14f3fbfc82 chore(deps): update dependency @types/node to ^22.13.9 (#2489)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-03 18:21:14 +00:00
homarr-renovate[bot] 6135b59b7d fix(deps): update tanstack-query monorepo to ^5.67.1 (#2487)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-03 16:20:08 +00:00
homarr-renovate[bot] bad07cbf25 fix(deps): update tanstack-query monorepo to ^5.67.0 (#2486)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-03 15:54:49 +00:00
homarr-renovate[bot] 49b0f962e0 fix(deps): update dependency prettier to ^3.5.3 (#2485)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-03 02:25:21 +00:00
homarr-crowdin[bot] c94fa4e999 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-03 00:48:29 +00:00
homarr-renovate[bot] be771e5630 chore(deps): update dependency prettier-plugin-packagejson to ^2.5.10 (#2483)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-02 22:54:45 +00:00
Meier Lukas a5e0e8c129 feat: add sigterm support (#2472) 2025-03-02 20:28:11 +01:00
Jack Weller 7dfb108a56 feat: added bordercolor option for dynamic section (#2334) 2025-03-02 11:39:17 +01:00
Meier Lukas 7dfc3646b7 feat(integration): add emby integration (#2466)
* feat(integration): add emby integration

* fix: deepsource issue
2025-03-02 10:56:01 +01:00
Meier Lukas d66610b324 refactor: replace drizzle count with $count (#2471) 2025-03-02 10:54:44 +01:00
Meier Lukas 9eb76634d0 fix(logs): add special case for axios error to prevent huge error messages (#2468) 2025-03-02 10:54:35 +01:00
homarr-crowdin[bot] e1d69f91e7 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-02 00:49:50 +00:00
Meier Lukas 80c2040b13 feat(media-request): show request status (#2465) 2025-03-01 22:44:38 +01:00
Meier Lukas 43619e0cc0 fix(media-request): inconsistent sorting and reordering (#2464) 2025-03-01 22:44:26 +01:00
Meier Lukas 6fad48f65a feat: use fetch with trusted certificates for oidc (#2412)
* feat: use fetch with trusted certificates for oidc

* fix: change custom-fetch symbol from auth-core to next-auth

* test: add mock for next-auth in events test

* refactor: use package import instead of relative import
2025-03-01 17:24:31 +01:00
Meier Lukas 788304adfb fix(old-import): default logo and favicon not replaced (#2456) 2025-03-01 17:24:07 +01:00
Meier Lukas c0e354428a fix(boards): case-sensitive board names in url (#2454) 2025-03-01 17:23:31 +01:00
Meier Lukas 286cc0fcac chore(license): update license property in package-json to match repository license (#2453) 2025-03-01 17:23:00 +01:00
homarr-renovate[bot] d9ef1b0470 fix(deps): update mantine monorepo to ^7.17.1 (#2462)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-01 09:45:24 +00:00
homarr-crowdin[bot] 163e3b007f chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-03-01 09:31:58 +00:00
homarr-renovate[bot] f4b302bbf8 chore(deps): update dependency @types/node to ^22.13.8 (#2460)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-03-01 06:56:23 +00:00
homarr-renovate[bot] 3c1cdb5e6e chore(deps): update dependency @types/node to ^22.13.7 (#2455)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 22:18:06 +00:00
Meier Lukas f0b932432b chore(docs): update docs-sitemap 2025-02-28 22:56:48 +01:00
homarr-renovate[bot] df13d67b42 chore(deps): update dependency @types/node to ^22.13.6 (#2452)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 21:17:25 +00:00
Releases Homarr 932426550b chore(release): 1.8.0 [skip ci] 2025-02-28 19:15:23 +00:00
homarr-releases[bot] d0ede4d643 chore(release): automatic release v1.8.0 2025-02-28 19:14:31 +00:00
homarr-renovate[bot] 14da6727e0 chore(deps): update dependency typescript to ^5.8.2 (#2450)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 17:17:33 +00:00
homarr-renovate[bot] a88c1ba440 fix(deps): update dependency eslint-plugin-react-hooks to ^5.2.0 (#2449)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 15:47:55 +00:00
homarr-renovate[bot] 5537f95b85 fix(deps): update tanstack-query monorepo to ^5.66.11 (#2447)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 14:16:26 +00:00
homarr-renovate[bot] d8e7dfa2fa chore(deps): update dependency prettier-plugin-packagejson to ^2.5.9 (#2446)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 11:54:56 +00:00
homarr-renovate[bot] 06ba0f0e9f fix(deps): update dependency undici to v7.4.0 (#2445)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 11:16:57 +00:00
homarr-renovate[bot] 11d2972713 chore(deps): update dependency proxmox-api&gt;undici to v7.4.0 (#2444)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 11:16:07 +00:00
homarr-renovate[bot] 4483dc8bcd fix(deps): update tanstack-query monorepo to ^5.66.10 (#2443)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-28 10:39:10 +00:00
Manuel 50367eb2f5 fix: chinese traditional locale (#2440) 2025-02-27 21:49:41 +01:00
Meier Lukas fdd91f585d fix(deps): downgrade to next 15.1.7 cause of turbopack crash with 15.2.0 and above (#2438) 2025-02-27 20:45:22 +01:00
homarr-renovate[bot] add91701de fix(deps): update dependency swagger-ui-react to ^5.20.0 (#2436)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-27 10:55:29 +00:00
homarr-renovate[bot] 8c1308c97f fix(deps): update dependency @auth/core to ^0.38.0 (#2434)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-27 10:39:05 +00:00
homarr-renovate[bot] b2cc97e316 fix(deps): update dependency @auth/drizzle-adapter to ^1.8.0 (#2435)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-27 10:18:38 +00:00
homarr-renovate[bot] 46ff689a7e chore(deps): update pnpm to v10.5.2 (#2431)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-27 02:21:20 +00:00
homarr-crowdin[bot] 2b40233235 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-02-27 00:46:24 +00:00
homarr-renovate[bot] d6939e4a6d fix(deps): update nextjs monorepo to ^15.2.0 (#2428)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-26 23:34:48 +00:00
homarr-renovate[bot] c2d6e2efcf fix(deps): update dependency eslint-config-prettier to ^10.0.2 (#2427)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-26 14:18:43 +00:00
homarr-renovate[bot] 0f2fc0505c chore(deps): update pnpm to v10.5.1 (#2426)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-26 12:26:24 +00:00
homarr-renovate[bot] faf7322bcb fix(deps): update dependency drizzle-orm to ^0.40.0 (#2425)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-25 21:53:58 +00:00
homarr-renovate[bot] 3b830ae098 fix(deps): update dependency drizzle-kit to ^0.30.5 (#2423)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-25 20:47:29 +00:00
homarr-renovate[bot] a6f91998c3 fix(deps): update turbo monorepo to ^2.4.4 (#2424)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-25 20:47:13 +00:00
homarr-renovate[bot] 874414fc4f fix(deps): update turbo monorepo to ^2.4.3 (#2422)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-25 13:46:48 +00:00
homarr-renovate[bot] fda3aff170 chore(deps): update pnpm to v10.5.0 (#2421)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-25 13:03:54 +00:00
homarr-renovate[bot] a9a37afd44 fix(deps): update dependency sass to ^1.85.1 (#2418)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-25 02:22:33 +00:00
homarr-renovate[bot] 2f3d297c46 chore(deps): update dependency @types/dockerode to ^3.3.35 (#2415)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-25 00:58:36 +00:00
homarr-crowdin[bot] 8355bb5919 chore(lang): updated translations from crowdin
Co-authored-by: Crowdin Homarr <190541745+homarr-crowdin[bot]@users.noreply.github.com>
2025-02-25 00:47:03 +00:00
homarr-renovate[bot] 46070fa5a3 chore(deps): update vitest monorepo to ^3.0.7 (#2414)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-24 18:22:08 +00:00
homarr-renovate[bot] 593c50bb8f fix(deps): update dependency typescript-eslint to ^8.25.0 (#2413)
Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
2025-02-24 17:44:09 +00:00
Meier Lukas 508f9afeb5 fix(boards): add scrollarea to board-select (#2409) 2025-02-24 17:46:57 +01:00
Meier Lukas ef9289d945 chore(docs): update docs-sitemap 2025-02-23 20:26:07 +01:00
Meier Lukas 9c892eacfc ci: add arm64 docker build (#2383) 2025-02-23 20:06:45 +01:00
Meier Lukas 7761dc29c8 feat(boards): add responsive layout system (#2271) 2025-02-23 17:34:56 +01:00
Meier Lukas 2085b5ece2 fix: await params for board metadata (#2406) 2025-02-23 15:14:41 +01:00
Meier Lukas c5107b2b67 fix: update checker logs incorrectly (#2402) 2025-02-23 12:55:38 +01:00
568 changed files with 57367 additions and 10372 deletions

No files matched your search

+1
View File
@@ -1,6 +1,7 @@
Dockerfile
.dockerignore
node_modules
**/node_modules
npm-debug.log
README.md
.next
+4 -1
View File
@@ -34,4 +34,7 @@ DB_URL='FULL_PATH_TO_YOUR_SQLITE_DB_FILE'
# If it is used, please use the full path to the directory where the certificates are stored.
# LOCAL_CERTIFICATE_PATH='FULL_PATH_TO_CERTIFICATES'
TURBO_TELEMETRY_DISABLED=1
TURBO_TELEMETRY_DISABLED=1
# Enable kubernetes tool
# ENABLE_KUBERNETES=true
+13
View File
@@ -31,6 +31,19 @@ body:
label: Version
description: What version of Homarr are you running?
options:
- 1.18.0
- 1.17.0
- 1.16.0
- 1.15.0
- 1.14.0
- 1.13.1
- 1.13.0
- 1.12.0
- 1.11.0
- 1.10.0
- 1.9.0
- 1.8.0
- 1.7.0
- 1.6.0
- 1.5.0
- 1.4.0
-5
View File
@@ -6,11 +6,6 @@
matchPackagePatterns: ["^@homarr/"],
enabled: false,
},
// Disable Dockerode updates see https://github.com/apocas/dockerode/issues/787
{
matchPackagePatterns: ["^dockerode$"],
enabled: false,
},
{
matchUpdateTypes: ["minor", "patch", "pin", "digest"],
automerge: true,
+93 -28
View File
@@ -15,13 +15,14 @@ on:
description: Send notifications
permissions:
contents: write
packages: write
contents: write # Required to update package.json version
packages: write # Required for pushing to GHCR
env:
SKIP_ENV_VALIDATION: true
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
GHCR_REPO: ghcr.io/${{ github.repository }}
TURBO_TELEMETRY_DISABLED: 1
concurrency:
@@ -102,59 +103,123 @@ jobs:
git pull origin dev
git rebase ${{ github.ref_name }}
git push origin dev
deploy:
name: Deploy docker image
build-amd64:
name: Build docker image for amd64
needs: release
runs-on: ubuntu-latest
env:
NEXT_VERSION: ${{ needs.release.outputs.version }}
DEPLOY_LATEST: ${{ github.ref_name == 'main' }}
DEPLOY_BETA: ${{ github.ref_name == 'beta' }}
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.release.outputs.git_ref }}
- name: Discord notification
if: ${{ github.events.inputs.send-notifications != false }}
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
uses: Ilshidur/action-discord@master
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
args: "Deployment of an image for version '${{env.NEXT_VERSION}}' has been triggered: [run ${{ github.run_number }}](<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}>)"
images: "${{ env.GHCR_REPO }}"
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
context: .
network: host
platforms: linux/amd64
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=${{ env.GHCR_REPO }}",push-by-digest=true,name-canonical=true,push=true
env:
SKIP_ENV_VALIDATION: true
build-arm64:
name: Build docker image for arm64
needs: release
runs-on: ubuntu-24.04-arm
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ needs.release.outputs.git_ref }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
tags: |
${{ env.DEPLOY_LATEST == 'true' && 'type=raw,value=latest' || null }}
${{ env.DEPLOY_BETA == 'true' && 'type=raw,value=beta' || null }}
type=raw,value=${{ env.NEXT_VERSION }}
- name: Build and push
id: buildPushAction
images: "${{ env.GHCR_REPO }}"
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push by digest
id: build
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
network: host
platforms: linux/arm64
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,"name=${{ env.GHCR_REPO }}",push-by-digest=true,name-canonical=true,push=true
env:
SKIP_ENV_VALIDATION: true
publish:
name: Complete deployment and notify
needs: [release, build-amd64, build-arm64]
runs-on: ubuntu-latest
env:
NEXT_VERSION: ${{ needs.release.outputs.version }}
DEPLOY_LATEST: ${{ github.ref_name == 'main' }}
DEPLOY_BETA: ${{ github.ref_name == 'beta' }}
steps:
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Publish beta
if: env.DEPLOY_BETA == 'true'
run: |
docker buildx imagetools create -t ${{ env.GHCR_REPO }}:beta \
${{ env.GHCR_REPO }}@${{ needs.build-amd64.outputs.digest }} \
${{ env.GHCR_REPO }}@${{ needs.build-arm64.outputs.digest }}
- name: Publish latest
if: env.DEPLOY_LATEST == 'true'
run: |
docker buildx imagetools create -t ${{ env.GHCR_REPO }}:latest \
${{ env.GHCR_REPO }}@${{ needs.build-amd64.outputs.digest }} \
${{ env.GHCR_REPO }}@${{ needs.build-arm64.outputs.digest }}
- name: Publish version
run: |
docker buildx imagetools create -t ${{ env.GHCR_REPO }}:${{ env.NEXT_VERSION }} \
${{ env.GHCR_REPO }}@${{ needs.build-amd64.outputs.digest }} \
${{ env.GHCR_REPO }}@${{ needs.build-arm64.outputs.digest }}
- name: Discord notification
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
uses: Ilshidur/action-discord@master
with:
args: "Deployment of image has completed for branch ${{ github.ref_name }}. Image ID is '${{ steps.buildPushAction.outputs.imageid }}'."
args: "Successfully deployed images for branch **${{ github.ref_name }}**. Tagged as **${{env.NEXT_VERSION}}**."
+3
View File
@@ -65,3 +65,6 @@ e2e/shared/tmp
#personal backgrounds
apps/nextjs/public/images/background.png
# next-intl
en.d.json.ts
+1 -1
View File
@@ -1 +1 @@
22.14.0
22.15.0
+14
View File
@@ -0,0 +1,14 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All Tests" type="JavaScriptTestRunnerVitest" nameIsGenerated="true">
<node-interpreter value="project" />
<vitest-package value="$PROJECT_DIR$/node_modules/vitest" />
<working-dir value="$PROJECT_DIR$" />
<vitest-options value="--exclude e2e --coverage.enabled" />
<envs>
<env name="NODE_ENV" value="development" />
<env name="CI" value="true" />
</envs>
<scope-kind value="ALL" />
<method v="2" />
</configuration>
</component>
+4 -4
View File
@@ -12,17 +12,17 @@ languageIds:
# You should unescape RegEx strings in order to fit in the YAML file
# To help with this, you can use https://www.freeformatter.com/json-escape.html
usageMatchRegex:
# The following example shows how to detect `t("your.i18n.keys")`
# the `{key}` will be placed by a proper keypath matching regex,
# you can ignore it and use your own matching rules as well
# For direct t("your.i18n.keys") usage
- "[^\\w\\d]t\\(['\"`]({key})['\"`]"
# For variable t assigned from getScopedI18n or useScopedI18n
- "\\bt\\(['\"`]({key})['\"`]\\)"
# A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys
# and works like how the i18next framework identifies the namespace scope from the
# useTranslation() hook.
# You should unescape RegEx strings in order to fit in the YAML file
# To help with this, you can use https://www.freeformatter.com/json-escape.html
scopeRangeRegex: "(getScopedI18n|useScopedI18n)\\(\\s*['\"](.*?)['\"]\\)"
scopeRangeRegex: "(?:const|let|var)\\s+t\\s*=\\s*(?:await\\s+)?(?:getScopedI18n|useScopedI18n)\\(\\s*['\"](.*?)['\"]\\)"
# An array of strings containing refactor templates.
# The "$1" will be replaced by the keypath specified.
+1
View File
@@ -26,6 +26,7 @@
"Sabnzbd",
"SeDemal",
"Sonarr",
"sslverify",
"superjson",
"tabler",
"trpc",
+379
View File
@@ -1,3 +1,382 @@
## [1.19.0](https://github.com/homarr-labs/homarr/compare/v1.18.1...v1.19.0) (2025-05-02)
### Features
* **widget:** add prefetch for apps and bookmarks ([#2895](https://github.com/homarr-labs/homarr/issues/2895)) ([82c5361](https://github.com/homarr-labs/homarr/commit/82c53611122dd07e5639a902afa0a6a4fd8ed4e5))
### Bug Fixes
* **cookie:** parsing of header not working with percentage char ([#2989](https://github.com/homarr-labs/homarr/issues/2989)) ([547a8c3](https://github.com/homarr-labs/homarr/commit/547a8c34c58c88e6f0074df327f49aadf9ab07f4))
* **deps:** update dependency @t3-oss/env-nextjs to ^0.13.4 ([#2993](https://github.com/homarr-labs/homarr/issues/2993)) ([1a07fa9](https://github.com/homarr-labs/homarr/commit/1a07fa9af59e93f9ce5d70b72855bb070f5b5787))
* **deps:** update dependency tsx to v4.19.4 ([#2981](https://github.com/homarr-labs/homarr/issues/2981)) ([a2dbac5](https://github.com/homarr-labs/homarr/commit/a2dbac5ad73aa50af7f4b40076bb5fcfa61adf80))
* **deps:** update dependency typescript-eslint to ^8.31.1 ([#2979](https://github.com/homarr-labs/homarr/issues/2979)) ([284ea23](https://github.com/homarr-labs/homarr/commit/284ea239f71f49c74e3ea60fa5de2fd968f1675b))
* **deps:** update mantine monorepo to ^7.17.7 ([#3004](https://github.com/homarr-labs/homarr/issues/3004)) ([a70b0b7](https://github.com/homarr-labs/homarr/commit/a70b0b70479df8fff8a2d256995844bad1fb55a0))
* **deps:** update tanstack-query monorepo to ^5.74.11 ([#2984](https://github.com/homarr-labs/homarr/issues/2984)) ([3299ced](https://github.com/homarr-labs/homarr/commit/3299cedc04cd87c7f014f69a900e7c6e6c33d954))
* **deps:** update tanstack-query monorepo to ^5.74.7 ([#2924](https://github.com/homarr-labs/homarr/issues/2924)) ([f4ce76a](https://github.com/homarr-labs/homarr/commit/f4ce76ac13136c2f559d3aff019dcc2add7c98dd))
* **deps:** update tanstack-query monorepo to ^5.74.9 ([#2983](https://github.com/homarr-labs/homarr/issues/2983)) ([1012cad](https://github.com/homarr-labs/homarr/commit/1012cad0e32f43f46bbb4e89ade3f0eb7fa54313))
* **deps:** update tanstack-query monorepo to ^5.75.0 ([#2998](https://github.com/homarr-labs/homarr/issues/2998)) ([0d1b40c](https://github.com/homarr-labs/homarr/commit/0d1b40c381fc068c770480f81c6c7dcefce0ec86))
* **deps:** update tanstack-query monorepo to ^5.75.1 ([#3006](https://github.com/homarr-labs/homarr/issues/3006)) ([2b1c433](https://github.com/homarr-labs/homarr/commit/2b1c433cefe667d930ce5178cc1218ffb7fa43c0))
* **deps:** update testcontainers-node monorepo to ^10.25.0 ([#2997](https://github.com/homarr-labs/homarr/issues/2997)) ([a934529](https://github.com/homarr-labs/homarr/commit/a934529146a0f53a047d2e3e834145c62c8ee891))
* **deps:** update tiptap monorepo to v2.11.9 ([#2987](https://github.com/homarr-labs/homarr/issues/2987)) ([70686a0](https://github.com/homarr-labs/homarr/commit/70686a00662a7f690efbb45920e5c45ad4a866ef))
* **deps:** update trpc monorepo to ^11.1.2 ([#2982](https://github.com/homarr-labs/homarr/issues/2982)) ([b10f33b](https://github.com/homarr-labs/homarr/commit/b10f33bf0b976217b2076ce84d8d1d9219b36e4c))
* **media-request:** add missing completed status ([#2990](https://github.com/homarr-labs/homarr/issues/2990)) ([9006d3d](https://github.com/homarr-labs/homarr/commit/9006d3d2fc21be5ba2eae616e467113356c91ebe))
* **releases-widget:** improve ui for smaller widgets ([#2962](https://github.com/homarr-labs/homarr/issues/2962)) ([f39a21c](https://github.com/homarr-labs/homarr/commit/f39a21c2962530298274ee705f3d85da023ea3e0))
* **unifi:** port is ignored ([#2995](https://github.com/homarr-labs/homarr/issues/2995)) ([0c9c5b8](https://github.com/homarr-labs/homarr/commit/0c9c5b8955c883191e5b6b137660c1a3cbd16ce4))
## [1.18.1](https://github.com/homarr-labs/homarr/compare/v1.18.0...v1.18.1) (2025-04-27)
### Bug Fixes
* cannot find module http-cookie-agent/http ([#2972](https://github.com/homarr-labs/homarr/issues/2972)) ([bb92f5b](https://github.com/homarr-labs/homarr/commit/bb92f5bb79e8f236dd149e87d14c1a35955140c7))
* **deps:** update dependency mysql2 to v3.14.1 ([#2969](https://github.com/homarr-labs/homarr/issues/2969)) ([5f80beb](https://github.com/homarr-labs/homarr/commit/5f80bebef2bd1598ad02dd1e169a1a6c27a4c143))
## [1.18.0](https://github.com/homarr-labs/homarr/compare/v1.17.0...v1.18.0) (2025-04-25)
### Features
* add releases widget ([#2497](https://github.com/homarr-labs/homarr/issues/2497)) ([3dcee8c](https://github.com/homarr-labs/homarr/commit/3dcee8cb869dd11d54631636253ad17e2af97dd7))
* **media-server:** add option to only show playing sessions ([#2899](https://github.com/homarr-labs/homarr/issues/2899)) ([f98750d](https://github.com/homarr-labs/homarr/commit/f98750d0b3e96b234d6f57b82bf7aa8729a091f2))
* migrate to unifi package ([#2894](https://github.com/homarr-labs/homarr/issues/2894)) ([8550c69](https://github.com/homarr-labs/homarr/commit/8550c69d51497676b654e204a85cdc84e8a38e30))
* **widgets:** add title to advanced options ([#2909](https://github.com/homarr-labs/homarr/issues/2909)) ([c64d903](https://github.com/homarr-labs/homarr/commit/c64d903f2b6375970325fb5031afd468dbf0ae11))
### Bug Fixes
* **certificates:** improve validation and prevent crash ([#2910](https://github.com/homarr-labs/homarr/issues/2910)) ([c514247](https://github.com/homarr-labs/homarr/commit/c51424717ddce5a2f4110658a1fbfab375185f66))
* **deps:** update dependency @auth/core to ^0.39.0 ([#2904](https://github.com/homarr-labs/homarr/issues/2904)) ([b0d7f9a](https://github.com/homarr-labs/homarr/commit/b0d7f9a48c05d380ff84ed7f48c9a9fd8dc33602))
* **deps:** update dependency @auth/drizzle-adapter to ^1.9.0 ([#2905](https://github.com/homarr-labs/homarr/issues/2905)) ([fdf700d](https://github.com/homarr-labs/homarr/commit/fdf700dba51d0bc4e72cdd63a63acb99c2196329))
* **deps:** update dependency @ctrl/qbittorrent to ^9.6.0 ([#2914](https://github.com/homarr-labs/homarr/issues/2914)) ([3d50808](https://github.com/homarr-labs/homarr/commit/3d508088d5a7d7fda53f49c196c2c6dd84d598d1))
* **deps:** update dependency @t3-oss/env-nextjs to ^0.13.0 ([#2935](https://github.com/homarr-labs/homarr/issues/2935)) ([eb95ee2](https://github.com/homarr-labs/homarr/commit/eb95ee285b727a8bda7ac9df3f75c25ced475358))
* **deps:** update dependency dockerode to ^4.0.6 ([#2901](https://github.com/homarr-labs/homarr/issues/2901)) ([593e3ee](https://github.com/homarr-labs/homarr/commit/593e3ee5a6f9cb8d50a51262c85c3c067fce0691))
* **deps:** update dependency drizzle-orm to ^0.43.0 ([#2939](https://github.com/homarr-labs/homarr/issues/2939)) ([295cc4a](https://github.com/homarr-labs/homarr/commit/295cc4a3c41ba9ad20e93df9d6ea5627d56d310d))
* **deps:** update dependency drizzle-orm to ^0.43.1 ([#2947](https://github.com/homarr-labs/homarr/issues/2947)) ([1d28bf4](https://github.com/homarr-labs/homarr/commit/1d28bf4c93c43c1956c5b386ca8a02ca6ae59eb5))
* **deps:** update dependency glob to ^11.0.2 ([#2931](https://github.com/homarr-labs/homarr/issues/2931)) ([573d5f8](https://github.com/homarr-labs/homarr/commit/573d5f89d6576020c3a4393372a56f8f75628e58))
* **deps:** update dependency next-auth to v5.0.0-beta.26 ([#2906](https://github.com/homarr-labs/homarr/issues/2906)) ([6e6edc8](https://github.com/homarr-labs/homarr/commit/6e6edc8a0d809614588967b51751257929a6ccd3))
* **deps:** update dependency next-auth to v5.0.0-beta.27 ([#2940](https://github.com/homarr-labs/homarr/issues/2940)) ([2533083](https://github.com/homarr-labs/homarr/commit/253308357a55ab2fac7ac4144215beefdc517b8d))
* **deps:** update dependency next-intl to v4.0.3 ([#2922](https://github.com/homarr-labs/homarr/issues/2922)) ([3172e6e](https://github.com/homarr-labs/homarr/commit/3172e6e0c4e55f62a7ee32ca84fcaa940e774565))
* **deps:** update dependency next-intl to v4.1.0 ([#2938](https://github.com/homarr-labs/homarr/issues/2938)) ([767fe94](https://github.com/homarr-labs/homarr/commit/767fe946d78268eddce6e213665176b8c6397e92))
* **deps:** update dependency sass to ^1.87.0 ([#2921](https://github.com/homarr-labs/homarr/issues/2921)) ([fed28bd](https://github.com/homarr-labs/homarr/commit/fed28bd77546be83b9965bd1116996b621f6b639))
* **deps:** update dependency trpc-to-openapi to ^2.2.0 ([#2903](https://github.com/homarr-labs/homarr/issues/2903)) ([2bf67c3](https://github.com/homarr-labs/homarr/commit/2bf67c3de8609eb504e322d830f507973a55d6fc))
* **deps:** update dependency tsdav to ^2.1.4 ([#2944](https://github.com/homarr-labs/homarr/issues/2944)) ([d78b2e1](https://github.com/homarr-labs/homarr/commit/d78b2e1e85a6c72ce1366e50ee4a1e83176b7913))
* **deps:** update dependency typescript-eslint to ^8.31.0 ([#2919](https://github.com/homarr-labs/homarr/issues/2919)) ([7aa3790](https://github.com/homarr-labs/homarr/commit/7aa379076da24c90238dd5fe2714dbceb3b84c2a))
* **deps:** update mantine monorepo to ^7.17.5 ([#2937](https://github.com/homarr-labs/homarr/issues/2937)) ([aba963c](https://github.com/homarr-labs/homarr/commit/aba963c7cf0d554d51e5fc233e546e4917ecdf67))
* **deps:** update trpc monorepo to ^11.1.1 ([#2927](https://github.com/homarr-labs/homarr/issues/2927)) ([bd3535d](https://github.com/homarr-labs/homarr/commit/bd3535dcf84569b87cf647bc5e0b957667b7e199))
* **deps:** update turbo monorepo to ^2.5.1 ([#2934](https://github.com/homarr-labs/homarr/issues/2934)) ([7766c3c](https://github.com/homarr-labs/homarr/commit/7766c3cbbc1187f6c38157fe15182c8b7d329acf))
* **deps:** update turbo monorepo to ^2.5.2 ([#2949](https://github.com/homarr-labs/homarr/issues/2949)) ([d97e740](https://github.com/homarr-labs/homarr/commit/d97e74047dc107abb05ca65d8a91a41c6071fbd4))
## [1.17.0](https://github.com/homarr-labs/homarr/compare/v1.16.0...v1.17.0) (2025-04-18)
### Features
* add api-key support for tdarr ([#2890](https://github.com/homarr-labs/homarr/issues/2890)) ([3d68f4d](https://github.com/homarr-labs/homarr/commit/3d68f4d1283b6cb27f9532d1adf52cef78a0fb03))
* Prefer primary color ([#2665](https://github.com/homarr-labs/homarr/issues/2665)) ([00053bd](https://github.com/homarr-labs/homarr/commit/00053bda7bbcaaf359074c3b35573ee0afc1409d))
### Bug Fixes
* calculate available space correctly and filter unmounted drives ([#2885](https://github.com/homarr-labs/homarr/issues/2885)) ([cfca0ba](https://github.com/homarr-labs/homarr/commit/cfca0ba58323ec09f8f64da2fee251ef14ba914a))
* **deps:** update dependency drizzle-kit to ^0.31.0 ([#2881](https://github.com/homarr-labs/homarr/issues/2881)) ([97390c6](https://github.com/homarr-labs/homarr/commit/97390c60300f3d16dabf0710fa435c6b3ae86a6f))
* **deps:** update dependency drizzle-orm to ^0.42.0 ([#2882](https://github.com/homarr-labs/homarr/issues/2882)) ([47d7abc](https://github.com/homarr-labs/homarr/commit/47d7abc0d739b91328834e0eaea033637632f22c))
* **deps:** update dependency jotai to ^2.12.3 ([#2868](https://github.com/homarr-labs/homarr/issues/2868)) ([c57b63b](https://github.com/homarr-labs/homarr/commit/c57b63b506733459ea0c09776917042fa878829b))
* **deps:** update dependency recharts to ^2.15.3 ([#2893](https://github.com/homarr-labs/homarr/issues/2893)) ([5fcb7a3](https://github.com/homarr-labs/homarr/commit/5fcb7a3b9c279c1b402e120a4a6f08265e8d5912))
* **deps:** update dependency swagger-ui-react to ^5.21.0 ([#2866](https://github.com/homarr-labs/homarr/issues/2866)) ([ff1263b](https://github.com/homarr-labs/homarr/commit/ff1263b217e96cbb2bc6b8e98ff117c44ca9f00d))
* **deps:** update dependency typescript-eslint to ^8.30.0 ([#2873](https://github.com/homarr-labs/homarr/issues/2873)) ([089734b](https://github.com/homarr-labs/homarr/commit/089734b293a21d6eeaa7c5df5ee9930853ed2fcf))
* **deps:** update dependency typescript-eslint to ^8.30.1 ([#2876](https://github.com/homarr-labs/homarr/issues/2876)) ([fdca513](https://github.com/homarr-labs/homarr/commit/fdca513929e9e594af2d59ad17c915cbc7ac2e08))
* **deps:** update dependency zod to ^3.24.3 ([#2886](https://github.com/homarr-labs/homarr/issues/2886)) ([1bfe397](https://github.com/homarr-labs/homarr/commit/1bfe397d68a88037e35701aab8a7b4c9027ec1e3))
* **deps:** update nextjs monorepo to v15.3.1 ([#2889](https://github.com/homarr-labs/homarr/issues/2889)) ([d37cdbd](https://github.com/homarr-labs/homarr/commit/d37cdbd080c2b3a4df536ab7dad4fc4a4b3c915f))
* **deps:** update tanstack-query monorepo to ^5.73.3 ([#2860](https://github.com/homarr-labs/homarr/issues/2860)) ([4e6ab03](https://github.com/homarr-labs/homarr/commit/4e6ab037c9245103b05afe977e9c288082a2b539))
* **deps:** update tanstack-query monorepo to ^5.74.0 ([#2864](https://github.com/homarr-labs/homarr/issues/2864)) ([ac78e87](https://github.com/homarr-labs/homarr/commit/ac78e8704287f45d6a8ca26cba9b87146e1c6161))
* **deps:** update tanstack-query monorepo to ^5.74.2 ([#2869](https://github.com/homarr-labs/homarr/issues/2869)) ([bf4a1cf](https://github.com/homarr-labs/homarr/commit/bf4a1cf1e8c99ada97adf6ee118ddaafc00115e9))
* **deps:** update tanstack-query monorepo to ^5.74.3 ([#2871](https://github.com/homarr-labs/homarr/issues/2871)) ([02fb1b9](https://github.com/homarr-labs/homarr/commit/02fb1b9dae501e475353e8e2510e4f8938c4e124))
* **deps:** update tanstack-query monorepo to ^5.74.4 ([#2888](https://github.com/homarr-labs/homarr/issues/2888)) ([17174b6](https://github.com/homarr-labs/homarr/commit/17174b6b96ae16b480e2bc5eb9f8ab7b914bc843))
* Tdarr widget empty statistics tab ([#2883](https://github.com/homarr-labs/homarr/issues/2883)) ([2d12c1e](https://github.com/homarr-labs/homarr/commit/2d12c1e641398e20a70f8bfb24a48de02498496a))
* **widget:** format stock values and changes for better readability ([#2836](https://github.com/homarr-labs/homarr/issues/2836)) ([a29556e](https://github.com/homarr-labs/homarr/commit/a29556ee8ec50aa384a9a46f6f5a5fa5dfa4cdac))
## [1.16.0](https://github.com/homarr-labs/homarr/compare/v1.15.0...v1.16.0) (2025-04-11)
### Features
* **boards:** add quick app add menu item ([#2681](https://github.com/homarr-labs/homarr/issues/2681)) ([7a3c836](https://github.com/homarr-labs/homarr/commit/7a3c836a70a9b9656c6fe74fe6a4bf8e7166a030))
* support aria2 integration ([#2226](https://github.com/homarr-labs/homarr/issues/2226)) ([94263c4](https://github.com/homarr-labs/homarr/commit/94263c445b8a0d0cdbea70ebe45ef932b426204d))
### Bug Fixes
* **boards:** add missing upload button for background in settings ([#2853](https://github.com/homarr-labs/homarr/issues/2853)) ([4baec7e](https://github.com/homarr-labs/homarr/commit/4baec7e3ff33ac0973daf0ac1f0171e349787bdb))
* **deps:** update dependency dotenv to ^16.5.0 ([#2848](https://github.com/homarr-labs/homarr/issues/2848)) ([c84dd2f](https://github.com/homarr-labs/homarr/commit/c84dd2fd797ca674e4f553ddc71926e9b533daa4))
* **deps:** update dependency eslint-config-prettier to ^10.1.2 ([#2842](https://github.com/homarr-labs/homarr/issues/2842)) ([924a7d0](https://github.com/homarr-labs/homarr/commit/924a7d076ef8bdd67afcce2e9f850bf334b43c3a))
* **deps:** update dependency ioredis to v5.6.1 ([#2851](https://github.com/homarr-labs/homarr/issues/2851)) ([0ed6a79](https://github.com/homarr-labs/homarr/commit/0ed6a79a5bba25fa7a90bec00d3815b3fffae427))
* **deps:** update dependency octokit to ^4.1.3 ([#2847](https://github.com/homarr-labs/homarr/issues/2847)) ([4b0b892](https://github.com/homarr-labs/homarr/commit/4b0b89225000137f02f3b89376c46d4d01387128))
* **deps:** update dependency swagger-ui-react to ^5.20.8 ([#2844](https://github.com/homarr-labs/homarr/issues/2844)) ([45d285a](https://github.com/homarr-labs/homarr/commit/45d285a76ba46d4d4c594f1f2e822d784a281b72))
* **deps:** update dependency undici to v7.8.0 ([#2841](https://github.com/homarr-labs/homarr/issues/2841)) ([f13be4a](https://github.com/homarr-labs/homarr/commit/f13be4a70870aca99a7f49f5068dadcd7fe01c22))
* **deps:** update nextjs monorepo to v15.3.0 ([#2838](https://github.com/homarr-labs/homarr/issues/2838)) ([a1fa429](https://github.com/homarr-labs/homarr/commit/a1fa4297ead54a9f8c842b2d23001f725359e000))
* **deps:** update tanstack-query monorepo to ^5.72.2 ([#2834](https://github.com/homarr-labs/homarr/issues/2834)) ([f5e3138](https://github.com/homarr-labs/homarr/commit/f5e3138c8118295d8230c3655af1c3f11ee5d4ff))
* **deps:** update testcontainers-node monorepo to ^10.24.2 ([#2846](https://github.com/homarr-labs/homarr/issues/2846)) ([057ff2c](https://github.com/homarr-labs/homarr/commit/057ff2cfc1cf062a3c48deb28699df8e1ba89f75))
* **deps:** update trpc monorepo to ^11.1.0 ([#2850](https://github.com/homarr-labs/homarr/issues/2850)) ([0fe4ea9](https://github.com/homarr-labs/homarr/commit/0fe4ea9dd9cbfb2def1bede9db8eaf649f79f1b0))
## [1.15.0](https://github.com/homarr-labs/homarr/compare/v1.14.0...v1.15.0) (2025-04-09)
### Features
* **boards:** add upload buttons for background, favicon and logo ([#2770](https://github.com/homarr-labs/homarr/issues/2770)) ([e07b9e6](https://github.com/homarr-labs/homarr/commit/e07b9e6a88ff0aad0aa5dae2f32f648ad5f0c0a8))
* unifi controller integration ([#2236](https://github.com/homarr-labs/homarr/issues/2236)) ([c1cd563](https://github.com/homarr-labs/homarr/commit/c1cd56304872b5f7b2b49624c6f5018f750d126b))
### Bug Fixes
* **deps:** update dependency @kubernetes/client-node to ^1.1.2 ([#2825](https://github.com/homarr-labs/homarr/issues/2825)) ([b064304](https://github.com/homarr-labs/homarr/commit/b064304201ed2ce52162edd5bc9ab5131da7ac97))
* **deps:** update dependency ldapts to v7.4.0 ([#2815](https://github.com/homarr-labs/homarr/issues/2815)) ([275224e](https://github.com/homarr-labs/homarr/commit/275224ee68bb49f329a6765095b46ec249027aca))
* **deps:** update dependency swagger-ui-react to ^5.20.7 ([#2816](https://github.com/homarr-labs/homarr/issues/2816)) ([85f8d23](https://github.com/homarr-labs/homarr/commit/85f8d23da3f3ec17945d79ef8a5212c5ceeefe75))
* **deps:** update dependency typescript-eslint to ^8.29.1 ([#2821](https://github.com/homarr-labs/homarr/issues/2821)) ([17d9272](https://github.com/homarr-labs/homarr/commit/17d92727f24cf0e2491dc93fd7c72759a24bbd54))
* **deps:** update mantine monorepo to ^7.17.4 ([#2824](https://github.com/homarr-labs/homarr/issues/2824)) ([bd5dcb9](https://github.com/homarr-labs/homarr/commit/bd5dcb991c8bd476cefbae1b8b2f407dd8db1acb))
* **deps:** update nextjs monorepo to v15.2.5 ([#2828](https://github.com/homarr-labs/homarr/issues/2828)) ([0fc7ca7](https://github.com/homarr-labs/homarr/commit/0fc7ca7738aee2d86940f43e3593368d4102cc73))
* **deps:** update tanstack-query monorepo to ^5.72.0 ([#2817](https://github.com/homarr-labs/homarr/issues/2817)) ([df212cf](https://github.com/homarr-labs/homarr/commit/df212cf5114a970ad4aed84811cfc7a2e4be67b3))
* **deps:** update tanstack-query monorepo to ^5.72.1 ([#2823](https://github.com/homarr-labs/homarr/issues/2823)) ([c01d9a4](https://github.com/homarr-labs/homarr/commit/c01d9a4dc5aba540a2b333a94507d027e5fb8d99))
* **deps:** update testcontainers-node monorepo to ^10.24.1 ([#2831](https://github.com/homarr-labs/homarr/issues/2831)) ([092c95b](https://github.com/homarr-labs/homarr/commit/092c95bbe0be73ad3dedb13c7f84ba7c36ca14db))
* **deps:** update trpc monorepo to ^11.0.3 ([#2822](https://github.com/homarr-labs/homarr/issues/2822)) ([a821bd7](https://github.com/homarr-labs/homarr/commit/a821bd71f47e03a276a96af705bec90a00229e0f))
* **deps:** update trpc monorepo to ^11.0.4 ([#2827](https://github.com/homarr-labs/homarr/issues/2827)) ([75100d1](https://github.com/homarr-labs/homarr/commit/75100d1a4926b838682206189eac046d844dba13))
* **medias:** upload size limited by nginx to 1mb ([#2813](https://github.com/homarr-labs/homarr/issues/2813)) ([bf046a7](https://github.com/homarr-labs/homarr/commit/bf046a715cd6897792b2f1582d076c055063bf57))
* **performance:** remove turbopack flag to no longer go out of memory after ([#2803](https://github.com/homarr-labs/homarr/issues/2803)) ([c6102ed](https://github.com/homarr-labs/homarr/commit/c6102edff467082803769c488ce642500edcdd25))
* **security:** missing authorization check for changes to notebook widget ([#2832](https://github.com/homarr-labs/homarr/issues/2832)) ([3948f7f](https://github.com/homarr-labs/homarr/commit/3948f7f9a47cd4562c9b4fd8252f116b8a95c982))
## [1.14.0](https://github.com/homarr-labs/homarr/compare/v1.13.1...v1.14.0) (2025-04-04)
### Features
* **cli:** add cli command to recreate credentials admin ([#2779](https://github.com/homarr-labs/homarr/issues/2779)) ([6742532](https://github.com/homarr-labs/homarr/commit/674253262bd4853ebde85d229d666a38733a7026))
### Bug Fixes
* **deps:** update dependency @ctrl/qbittorrent to ^9.5.2 ([#2795](https://github.com/homarr-labs/homarr/issues/2795)) ([ea8bf43](https://github.com/homarr-labs/homarr/commit/ea8bf43d7b56f526fbf2d4a3955c2c179e4e74d8))
* **deps:** update dependency @kubernetes/client-node to ^1.1.1 ([#2793](https://github.com/homarr-labs/homarr/issues/2793)) ([76b8b35](https://github.com/homarr-labs/homarr/commit/76b8b35cc1f586797210bdcd3d848d64b5f36d63))
* **deps:** update dependency dockerode to ^4.0.5 ([#2757](https://github.com/homarr-labs/homarr/issues/2757)) ([db13fd0](https://github.com/homarr-labs/homarr/commit/db13fd03c018cb2f79f0b094b93b69d69fde97ff))
* **deps:** update dependency eslint-plugin-react to ^7.37.5 ([#2794](https://github.com/homarr-labs/homarr/issues/2794)) ([f9aeb8f](https://github.com/homarr-labs/homarr/commit/f9aeb8ffe3ff4cd65cd76c560a687912262a735f))
* **deps:** update dependency recharts to ^2.15.2 ([#2785](https://github.com/homarr-labs/homarr/issues/2785)) ([f33b1cb](https://github.com/homarr-labs/homarr/commit/f33b1cb5d0c317df5348e87e0f5f43fdc6044615))
* **deps:** update dependency sass to ^1.86.1 ([#2762](https://github.com/homarr-labs/homarr/issues/2762)) ([3e35051](https://github.com/homarr-labs/homarr/commit/3e3505176a7df01bae5173d7f62380fa17859e8f))
* **deps:** update dependency sass to ^1.86.2 ([#2784](https://github.com/homarr-labs/homarr/issues/2784)) ([3131082](https://github.com/homarr-labs/homarr/commit/3131082c778191be5568a93bbf5f10219f3c2be9))
* **deps:** update dependency sass to ^1.86.3 ([#2796](https://github.com/homarr-labs/homarr/issues/2796)) ([98ecc68](https://github.com/homarr-labs/homarr/commit/98ecc683e563475644530682f08d335ac3671a5e))
* **deps:** update dependency swagger-ui-react to ^5.20.3 ([#2777](https://github.com/homarr-labs/homarr/issues/2777)) ([81d1231](https://github.com/homarr-labs/homarr/commit/81d1231d8fc026dd9f1ba58e28937aba9d94d88e))
* **deps:** update dependency swagger-ui-react to ^5.20.4 ([#2786](https://github.com/homarr-labs/homarr/issues/2786)) ([85672d9](https://github.com/homarr-labs/homarr/commit/85672d9cf15bf48c9cc2fb4e746f65814f46361b))
* **deps:** update dependency swagger-ui-react to ^5.20.5 ([#2787](https://github.com/homarr-labs/homarr/issues/2787)) ([3363eeb](https://github.com/homarr-labs/homarr/commit/3363eebdddf10a028d1cdebcb4d581105ba1d63c))
* **deps:** update dependency swagger-ui-react to ^5.20.6 ([#2798](https://github.com/homarr-labs/homarr/issues/2798)) ([968a82b](https://github.com/homarr-labs/homarr/commit/968a82baf5d6adc64c680508493b77b892fdd5fc))
* **deps:** update dependency trpc-to-openapi to ^2.1.4 ([#2748](https://github.com/homarr-labs/homarr/issues/2748)) ([c69e331](https://github.com/homarr-labs/homarr/commit/c69e331ded3cfde837dcf28c8b1ba4a9b7a3c8aa))
* **deps:** update dependency trpc-to-openapi to ^2.1.5 ([#2799](https://github.com/homarr-labs/homarr/issues/2799)) ([b03941e](https://github.com/homarr-labs/homarr/commit/b03941ed80057154f0b4b04c764652ada1fdf18c))
* **deps:** update dependency typescript-eslint to ^8.29.0 ([#2761](https://github.com/homarr-labs/homarr/issues/2761)) ([3687c4b](https://github.com/homarr-labs/homarr/commit/3687c4b3d655d9cebb85fb3c3ad80f494e9a8f0a))
* **deps:** update dependency undici to v7.7.0 ([#2776](https://github.com/homarr-labs/homarr/issues/2776)) ([ff5c313](https://github.com/homarr-labs/homarr/commit/ff5c31342fe9eb668533d7d9f0d65ad3f01eba0a))
* **deps:** update tanstack-query monorepo to ^5.71.0 ([#2752](https://github.com/homarr-labs/homarr/issues/2752)) ([77044e8](https://github.com/homarr-labs/homarr/commit/77044e8e0b8e7267b8547eb1d0f86026948b292a))
* **deps:** update tanstack-query monorepo to ^5.71.1 ([#2756](https://github.com/homarr-labs/homarr/issues/2756)) ([0b8a009](https://github.com/homarr-labs/homarr/commit/0b8a0098bd02a71107af9702e39000227028ec20))
* **deps:** update tanstack-query monorepo to ^5.71.10 ([#2790](https://github.com/homarr-labs/homarr/issues/2790)) ([964368a](https://github.com/homarr-labs/homarr/commit/964368a06c8385df63a252e2d0759a2524348ac6))
* **deps:** update tanstack-query monorepo to ^5.71.3 ([#2767](https://github.com/homarr-labs/homarr/issues/2767)) ([858fe6e](https://github.com/homarr-labs/homarr/commit/858fe6e19a682bb0fa0cfa0d11c2423447fdad2f))
* **deps:** update tanstack-query monorepo to ^5.71.5 ([#2780](https://github.com/homarr-labs/homarr/issues/2780)) ([466d0e0](https://github.com/homarr-labs/homarr/commit/466d0e00530903ab4101cd2e94c00ab8a7c1c8ce))
* **deps:** update testcontainers-node monorepo to ^10.24.0 ([#2789](https://github.com/homarr-labs/homarr/issues/2789)) ([1b05041](https://github.com/homarr-labs/homarr/commit/1b0504198b41032319ead2604721abaaf08709d8))
* **deps:** update tiptap monorepo to v2.11.7 ([#2749](https://github.com/homarr-labs/homarr/issues/2749)) ([0ec8f23](https://github.com/homarr-labs/homarr/commit/0ec8f23b7c655889d8f6fb9fcfd66a9736eb5a10))
* **deps:** update tiptap monorepo to v2.11.7 ([#2750](https://github.com/homarr-labs/homarr/issues/2750)) ([59b1630](https://github.com/homarr-labs/homarr/commit/59b16305326ac811ad91e89c0786b9e6b1b7e1df))
* **deps:** update trpc monorepo to ^11.0.2 ([#2792](https://github.com/homarr-labs/homarr/issues/2792)) ([8886380](https://github.com/homarr-labs/homarr/commit/8886380f0a9ea7d35cd54182a378b2f47b71c283))
* **deps:** update turbo monorepo to ^2.5.0 ([#2791](https://github.com/homarr-labs/homarr/issues/2791)) ([0b41967](https://github.com/homarr-labs/homarr/commit/0b41967ec366d925dbb172d38c3677d88f51f0a9))
* **nextcloud:** issue with self signed certificates ([#2760](https://github.com/homarr-labs/homarr/issues/2760)) ([7f77130](https://github.com/homarr-labs/homarr/commit/7f77130978eb7f25e571b7315250c91656a85d78))
* update check blocks page loading ([#2782](https://github.com/homarr-labs/homarr/issues/2782)) ([29ff879](https://github.com/homarr-labs/homarr/commit/29ff879dfd1036d44b7c4735a0b269a83173b4d1))
### Reverts
* add restriction callback to restrict visibility and modification of widget kinds ([#2746](https://github.com/homarr-labs/homarr/issues/2746)) ([9851531](https://github.com/homarr-labs/homarr/commit/98515312a2439d1ed9fc5b412843ca625120b2ac))
## [1.13.1](https://github.com/homarr-labs/homarr/compare/v1.13.0...v1.13.1) (2025-03-28)
### Bug Fixes
* **deps:** update react monorepo to v19.1.0 ([#2734](https://github.com/homarr-labs/homarr/issues/2734)) ([94ff401](https://github.com/homarr-labs/homarr/commit/94ff401d7dface924f48affccbc59e3a98ed8dc1))
### Reverts
* ssg integration create ([#2736](https://github.com/homarr-labs/homarr/issues/2736)) ([fef50a5](https://github.com/homarr-labs/homarr/commit/fef50a53b1fb592668dfa9aade6b110e42aec9a8))
## [1.13.0](https://github.com/homarr-labs/homarr/compare/v1.12.0...v1.13.0) (2025-03-28)
### Features
* add default search engines seeding / set homarr docs as global server search engine ([#2663](https://github.com/homarr-labs/homarr/issues/2663)) ([3e1c000](https://github.com/homarr-labs/homarr/commit/3e1c000d515c0edc6f49241fc381187e1829ca7e))
* add german swiss locale ([#2726](https://github.com/homarr-labs/homarr/issues/2726)) ([eba738e](https://github.com/homarr-labs/homarr/commit/eba738e5d6594d46b5b7d1eab875fc8060e0fe7b))
* add jetbrains run profile ([#2704](https://github.com/homarr-labs/homarr/issues/2704)) ([07f0abf](https://github.com/homarr-labs/homarr/commit/07f0abf28cb31f81860e623c70970e16d17e2836))
* add title to dynamic section ([#2614](https://github.com/homarr-labs/homarr/issues/2614)) ([1dd7b1a](https://github.com/homarr-labs/homarr/commit/1dd7b1a6b97f75bca0d1a5c0dbb4254aa4bbd418))
* app dropdown add infinity scroll ([#2696](https://github.com/homarr-labs/homarr/issues/2696)) ([8bf893b](https://github.com/homarr-labs/homarr/commit/8bf893b39292f34f5c697c09ba2c9e53c8a6ea90))
* **auth:** add env variable to force user-info usage instead of idtoken ([#2711](https://github.com/homarr-labs/homarr/issues/2711)) ([94d3dad](https://github.com/homarr-labs/homarr/commit/94d3dad909c39cec096ff61c0a2f45e8853b6111))
* auto sign-in when creating the initial user ([#2664](https://github.com/homarr-labs/homarr/issues/2664)) ([46c95e0](https://github.com/homarr-labs/homarr/commit/46c95e0da3ad27eb072efc45250abb0baf3e2483))
* implement auto-select icon ([#2679](https://github.com/homarr-labs/homarr/issues/2679)) ([1a3a559](https://github.com/homarr-labs/homarr/commit/1a3a55934d8b3e4703e0ce44d9d26ad7ff100aca))
* **lang:** add english uk language ([#2715](https://github.com/homarr-labs/homarr/issues/2715)) ([93c64ba](https://github.com/homarr-labs/homarr/commit/93c64baec294c39cd490a85f8b06b57d53fc82b3))
* **logs:** improve logs by logging errors with causes and metadata ([#2703](https://github.com/homarr-labs/homarr/issues/2703)) ([579dd57](https://github.com/homarr-labs/homarr/commit/579dd5763d139e1644c2e192620728afa54c96d2))
* set home board when creating first board ([#2683](https://github.com/homarr-labs/homarr/issues/2683)) ([8f7f211](https://github.com/homarr-labs/homarr/commit/8f7f2110ec29db12ea2d83cd779ec86851209188))
* SSG integration creation page ([#2684](https://github.com/homarr-labs/homarr/issues/2684)) ([ce0705e](https://github.com/homarr-labs/homarr/commit/ce0705e9d4a502273a0d84e4e14d61a061fd21f9))
* **widget:** add restriction callback to restrict visibility and modification of widget kinds ([#2658](https://github.com/homarr-labs/homarr/issues/2658)) ([84f73d3](https://github.com/homarr-labs/homarr/commit/84f73d33a061a1d243803078b245a8016a615af9))
### Bug Fixes
* allow deletion of external users ([#2725](https://github.com/homarr-labs/homarr/issues/2725)) ([40e0098](https://github.com/homarr-labs/homarr/commit/40e00987cb6f4ee58fdce1da9489eedd92b8843d))
* **auth:** fusion auth returns www-authenticate token response ([#2719](https://github.com/homarr-labs/homarr/issues/2719)) ([b5b0b06](https://github.com/homarr-labs/homarr/commit/b5b0b069d2029110d5618a29af5ae003030584d9))
* bookmarks layout ([#2675](https://github.com/homarr-labs/homarr/issues/2675)) ([8a071f9](https://github.com/homarr-labs/homarr/commit/8a071f9ab6bc4c85073dc52cc2e60da69f30950a))
* calendar indicators ([#2712](https://github.com/homarr-labs/homarr/issues/2712)) ([70ea093](https://github.com/homarr-labs/homarr/commit/70ea093eb6530d25d3e60e6d496651e3fc457826))
* **deps:** update dependency drizzle-kit to ^0.30.6 ([#2706](https://github.com/homarr-labs/homarr/issues/2706)) ([f03e381](https://github.com/homarr-labs/homarr/commit/f03e381aea414c5fb770c7ba092b31f9c53eee11))
* **deps:** update dependency drizzle-zod to ^0.7.1 ([#2717](https://github.com/homarr-labs/homarr/issues/2717)) ([569ec6f](https://github.com/homarr-labs/homarr/commit/569ec6fe5ccec980351162024170fabe06dcc3da))
* **deps:** update dependency ldapts to v7.3.3 ([#2691](https://github.com/homarr-labs/homarr/issues/2691)) ([00f5a87](https://github.com/homarr-labs/homarr/commit/00f5a877a6f09037eff4c9934fc273c4d2af0f6c))
* **deps:** update dependency swagger-ui-react to ^5.20.2 ([#2708](https://github.com/homarr-labs/homarr/issues/2708)) ([68407ea](https://github.com/homarr-labs/homarr/commit/68407eaa195894db37018cefeeca4ae2da085847))
* **deps:** update dependency typescript-eslint to ^8.28.0 ([#2693](https://github.com/homarr-labs/homarr/issues/2693)) ([f624611](https://github.com/homarr-labs/homarr/commit/f6246115405cdc85948059170742b0bae58ab337))
* **deps:** update dependency undici to v7.6.0 ([#2710](https://github.com/homarr-labs/homarr/issues/2710)) ([43b8cfa](https://github.com/homarr-labs/homarr/commit/43b8cfa4dd250013fdf15d509a072ba0984f9ab1))
* **deps:** update mantine monorepo to ^7.17.3 ([#2707](https://github.com/homarr-labs/homarr/issues/2707)) ([6854e47](https://github.com/homarr-labs/homarr/commit/6854e4729d3ba4a82a318813fec0a20eccdbed18))
* **deps:** update nextjs monorepo to v15.2.4 ([#2720](https://github.com/homarr-labs/homarr/issues/2720)) ([ac77bdd](https://github.com/homarr-labs/homarr/commit/ac77bdd84cba47a43d1952725a9c7feccd972766))
* **deps:** update tanstack-query monorepo to ^5.69.2 ([#2714](https://github.com/homarr-labs/homarr/issues/2714)) ([78b5520](https://github.com/homarr-labs/homarr/commit/78b55202e7f4739933768d27211556f927b04fed))
* **deps:** update tanstack-query monorepo to ^5.69.3 ([#2716](https://github.com/homarr-labs/homarr/issues/2716)) ([e7e80db](https://github.com/homarr-labs/homarr/commit/e7e80dbc7d62830ce1ce150b6e22a67220da8be8))
* **deps:** update tanstack-query monorepo to ^5.70.0 ([#2722](https://github.com/homarr-labs/homarr/issues/2722)) ([34eb9b3](https://github.com/homarr-labs/homarr/commit/34eb9b366fdc58c9fc03d18ac7dd68bff1ea83e6))
* **deps:** update testcontainers-node monorepo to ^10.22.0 ([#2692](https://github.com/homarr-labs/homarr/issues/2692)) ([b7a6d95](https://github.com/homarr-labs/homarr/commit/b7a6d950db557ea9deadc0be014b5f218611ac83))
* **deps:** update testcontainers-node monorepo to ^10.23.0 ([#2699](https://github.com/homarr-labs/homarr/issues/2699)) ([c3264b2](https://github.com/homarr-labs/homarr/commit/c3264b2fe10ad374e92eb16921d43427d7ca866b))
* **deps:** update tiptap monorepo to v2.11.6 ([#2718](https://github.com/homarr-labs/homarr/issues/2718)) ([0ed4c74](https://github.com/homarr-labs/homarr/commit/0ed4c741c59c3e498aa247adc292bdbbde1c59d3))
* **deps:** update trpc monorepo to ^11.0.1 ([#2724](https://github.com/homarr-labs/homarr/issues/2724)) ([2178185](https://github.com/homarr-labs/homarr/commit/217818573e8bd7d49a821afdf269cd8b3f3d442d))
* **import:** autofix missing shapes for sidebars and some sections as well ([#2723](https://github.com/homarr-labs/homarr/issues/2723)) ([62c7955](https://github.com/homarr-labs/homarr/commit/62c7955e48ca62b4bf1baf26ac6a12847795ac18))
* Media request via search engine ([#2677](https://github.com/homarr-labs/homarr/issues/2677)) ([5a8405a](https://github.com/homarr-labs/homarr/commit/5a8405a9a81257b023c0265309f7f530b2e23c7a))
### Reverts
* add development package and update workspace ([#2700](https://github.com/homarr-labs/homarr/issues/2700))" ([#2728](https://github.com/homarr-labs/homarr/issues/2728)) ([996ec54](https://github.com/homarr-labs/homarr/commit/996ec548c4b9c8561919409b81adc90b0a24fbd6))
## [1.12.0](https://github.com/homarr-labs/homarr/compare/v1.11.0...v1.12.0) (2025-03-21)
### Features
* stock price widget ([#2579](https://github.com/homarr-labs/homarr/issues/2579)) ([91a69c1](https://github.com/homarr-labs/homarr/commit/91a69c162a51cff8899eaa7d5a113f6ec8feafba))
### Bug Fixes
* **cli:** fix-usernames command only fixes lowercase usernames ([#2650](https://github.com/homarr-labs/homarr/issues/2650)) ([b0381cb](https://github.com/homarr-labs/homarr/commit/b0381cb8836b8477d0990c264aa399cb06b85237))
* **deps:** update dependency better-sqlite3 to ^11.9.1 ([#2632](https://github.com/homarr-labs/homarr/issues/2632)) ([289c7f1](https://github.com/homarr-labs/homarr/commit/289c7f1a60477024207261d486c2a88718320df7))
* **deps:** update dependency drizzle-orm to ^0.40.1 ([#2624](https://github.com/homarr-labs/homarr/issues/2624)) ([7ba2067](https://github.com/homarr-labs/homarr/commit/7ba2067689ed7fd3ab78e75a6ba385483a97b0a3))
* **deps:** update dependency drizzle-orm to ^0.41.0 ([#2666](https://github.com/homarr-labs/homarr/issues/2666)) ([8dee8f8](https://github.com/homarr-labs/homarr/commit/8dee8f8680f2282d76f6e727123220a60e2b596d))
* **deps:** update dependency mysql2 to v3.14.0 ([#2652](https://github.com/homarr-labs/homarr/issues/2652)) ([3e4d24b](https://github.com/homarr-labs/homarr/commit/3e4d24b28e998af80c00c8ad141660d4bfe5ef33))
* **deps:** update dependency sass to ^1.86.0 ([#2629](https://github.com/homarr-labs/homarr/issues/2629)) ([c9fecaa](https://github.com/homarr-labs/homarr/commit/c9fecaabb6416db5c55d9066ed782712cc96faa0))
* **deps:** update dependency typescript-eslint to ^8.27.0 ([#2653](https://github.com/homarr-labs/homarr/issues/2653)) ([e3fcfbe](https://github.com/homarr-labs/homarr/commit/e3fcfbe9166834e9443c5ead21c2f67b2d01ad2e))
* **deps:** update tanstack-query monorepo to ^5.69.0 ([#2634](https://github.com/homarr-labs/homarr/issues/2634)) ([2d2ae5a](https://github.com/homarr-labs/homarr/commit/2d2ae5a4191085404f8f7f790a4f0f62b86b408d))
* **deps:** update testcontainers-node monorepo to ^10.21.0 ([#2633](https://github.com/homarr-labs/homarr/issues/2633)) ([1519789](https://github.com/homarr-labs/homarr/commit/15197897ac3e2f3ed1dcc24c5f64748eaa52f98f))
* **permissions:** unable to edit board with full board permissions ([#2625](https://github.com/homarr-labs/homarr/issues/2625)) ([4cc3739](https://github.com/homarr-labs/homarr/commit/4cc37397c2e56a97e6b1173735da78824c7b15e5))
* prohibit dot in board name ([#2643](https://github.com/homarr-labs/homarr/issues/2643)) ([bb8cb6d](https://github.com/homarr-labs/homarr/commit/bb8cb6ddeda6906b3c43270ec9dd8ec66d27f0cd))
## [1.11.0](https://github.com/homarr-labs/homarr/compare/v1.10.0...v1.11.0) (2025-03-14)
### Features
* add nextcloud integration ([#2501](https://github.com/homarr-labs/homarr/issues/2501)) ([2e62a61](https://github.com/homarr-labs/homarr/commit/2e62a61f4d20241fb77065faa00b14d427d4f4e0))
* **calendar:** add show-unmonitored option ([#2547](https://github.com/homarr-labs/homarr/issues/2547)) ([f6f0d7c](https://github.com/homarr-labs/homarr/commit/f6f0d7c72bd4b91949f957e5e28ff60e6c82d2a5))
* **integrations:** add checkbox to add app ([#2463](https://github.com/homarr-labs/homarr/issues/2463)) ([22f9166](https://github.com/homarr-labs/homarr/commit/22f91666908c6a140fadd89f52f57a57a51cd935))
* **kubernetes:** add kubernetes tool ([#1929](https://github.com/homarr-labs/homarr/issues/1929)) ([f19aa29](https://github.com/homarr-labs/homarr/commit/f19aa29607640578f61d1842d4300cc0c0618896))
* **logs:** improve error logs with stacked causes ([#2574](https://github.com/homarr-labs/homarr/issues/2574)) ([3d4d32f](https://github.com/homarr-labs/homarr/commit/3d4d32f3773f006edc1d441ce419d7b97c26b526))
* **widgets:** add border color option to advanced-options ([#2512](https://github.com/homarr-labs/homarr/issues/2512)) ([b3464b3](https://github.com/homarr-labs/homarr/commit/b3464b3340cf57b4f85da0dd2e1bd8e754f1bec8))
### Bug Fixes
* action icons not being rendered ([#2593](https://github.com/homarr-labs/homarr/issues/2593)) ([85d2d61](https://github.com/homarr-labs/homarr/commit/85d2d6118495f3b466a1f014b90446d03c5ffdcb))
* **app:** improve responsive styles ([#2537](https://github.com/homarr-labs/homarr/issues/2537)) ([fb800a0](https://github.com/homarr-labs/homarr/commit/fb800a00084833e785deecdb3b6fde4e35ddf7b8))
* **bookmarks:** improve responsive styles ([#2536](https://github.com/homarr-labs/homarr/issues/2536)) ([df249a0](https://github.com/homarr-labs/homarr/commit/df249a0173c3a70711c99df3f7983729a64eaff9))
* **calendar:** dropdown spans over whole screen ([#2569](https://github.com/homarr-labs/homarr/issues/2569)) ([fbbfe9a](https://github.com/homarr-labs/homarr/commit/fbbfe9af293961afcb686f3e7a559b67b37f6743))
* **calendar:** improve responsive styles ([#2538](https://github.com/homarr-labs/homarr/issues/2538)) ([1db9c3c](https://github.com/homarr-labs/homarr/commit/1db9c3c6925f0baae963c5f079037c2bcd1cee44))
* **date-time:** improve responsive styles ([#2539](https://github.com/homarr-labs/homarr/issues/2539)) ([fd5b1b0](https://github.com/homarr-labs/homarr/commit/fd5b1b0c082ee440c6c5137629ef1ec4eead23eb))
* **deps:** update dependency @kubernetes/client-node to ^1.1.0 ([#2591](https://github.com/homarr-labs/homarr/issues/2591)) ([8a02c65](https://github.com/homarr-labs/homarr/commit/8a02c656488bf0f239b8f394d73ed63ade8f61ed))
* **deps:** update dependency better-sqlite3 to ^11.9.0 ([#2598](https://github.com/homarr-labs/homarr/issues/2598)) ([04c17d1](https://github.com/homarr-labs/homarr/commit/04c17d1c41f0c44e88e39cdfe116972da32624b4))
* **deps:** update dependency jotai to ^2.12.2 ([#2560](https://github.com/homarr-labs/homarr/issues/2560)) ([ff6ca86](https://github.com/homarr-labs/homarr/commit/ff6ca86a78ccec4a2dee3d08c1420948c4de28ee))
* **deps:** update dependency next-intl to v4 ([#2580](https://github.com/homarr-labs/homarr/issues/2580)) ([f55d8a9](https://github.com/homarr-labs/homarr/commit/f55d8a9c2ebbc612775d66b1f073605fb9e151f3))
* **deps:** update dependency next-intl to v4.0.1 ([#2585](https://github.com/homarr-labs/homarr/issues/2585)) ([d8247f2](https://github.com/homarr-labs/homarr/commit/d8247f2dc9a4aaa45d8e193db04295f51c44d4aa))
* **deps:** update dependency next-intl to v4.0.2 ([#2589](https://github.com/homarr-labs/homarr/issues/2589)) ([b607c57](https://github.com/homarr-labs/homarr/commit/b607c5702fd2bf86be8b56d7b7b00435363095e0))
* **deps:** update dependency prismjs to ^1.30.0 ([#2562](https://github.com/homarr-labs/homarr/issues/2562)) ([8cb8eaf](https://github.com/homarr-labs/homarr/commit/8cb8eaf9cc2aaa842869c6be75e9208b9a19fd77))
* **deps:** update dependency swagger-ui-react to ^5.20.1 ([#2558](https://github.com/homarr-labs/homarr/issues/2558)) ([9c582d9](https://github.com/homarr-labs/homarr/commit/9c582d906bb2702de5db282594293e51e94ca98d))
* **deps:** update dependency typescript-eslint to ^8.26.1 ([#2561](https://github.com/homarr-labs/homarr/issues/2561)) ([55ad0b0](https://github.com/homarr-labs/homarr/commit/55ad0b0a6533df44e7d1f6eecf33135654cea104))
* **deps:** update dependency undici to v7.5.0 ([#2583](https://github.com/homarr-labs/homarr/issues/2583)) ([56fe8dd](https://github.com/homarr-labs/homarr/commit/56fe8dd9e9ff14dc0c10a93f6798df11c2ef5761))
* **deps:** update dependency video.js to ^8.22.0 ([#2564](https://github.com/homarr-labs/homarr/issues/2564)) ([a102f39](https://github.com/homarr-labs/homarr/commit/a102f39518722d898d75d978df91ae2a7f8da3e9))
* **deps:** update dependency zod-form-data to ^2.0.6 ([#2572](https://github.com/homarr-labs/homarr/issues/2572)) ([2135f99](https://github.com/homarr-labs/homarr/commit/2135f9980b4eb9e682fd19d2a1536f50201a1bee))
* **deps:** update dependency zod-form-data to ^2.0.7 ([#2573](https://github.com/homarr-labs/homarr/issues/2573)) ([6c9fbd6](https://github.com/homarr-labs/homarr/commit/6c9fbd6c09b481b24dad849cc8d367d0c5591cdb))
* **deps:** update mantine monorepo to ^7.17.2 ([#2599](https://github.com/homarr-labs/homarr/issues/2599)) ([1e50ac4](https://github.com/homarr-labs/homarr/commit/1e50ac411c9e416de4225881b631e4cc497e7b0d))
* **deps:** update tanstack-query monorepo to ^5.67.3 ([#2567](https://github.com/homarr-labs/homarr/issues/2567)) ([8486073](https://github.com/homarr-labs/homarr/commit/8486073f271c69f767d9cc76fdd3f27cf1f9db20))
* **deps:** update tanstack-query monorepo to ^5.68.0 ([#2600](https://github.com/homarr-labs/homarr/issues/2600)) ([25f7406](https://github.com/homarr-labs/homarr/commit/25f7406283e2999b85fdc21953e0e6c572d8f23b))
* **deps:** update testcontainers-node monorepo to ^10.19.0 ([#2576](https://github.com/homarr-labs/homarr/issues/2576)) ([d669f99](https://github.com/homarr-labs/homarr/commit/d669f99ac161697d6c3db81c51b7bf25532fbbfd))
* **deps:** update testcontainers-node monorepo to ^10.20.0 ([#2602](https://github.com/homarr-labs/homarr/issues/2602)) ([75fb9db](https://github.com/homarr-labs/homarr/commit/75fb9dbf1e7c2137d1dd98bc2952ddb28fc0375f))
* **dns-controls:** improve responsive styles ([#2534](https://github.com/homarr-labs/homarr/issues/2534)) ([c0e1355](https://github.com/homarr-labs/homarr/commit/c0e1355d7f995e79eec23680568f1830e5f03542))
* **dns-hole-summary:** remove inconsistency for position of text ([#2568](https://github.com/homarr-labs/homarr/issues/2568)) ([e774b06](https://github.com/homarr-labs/homarr/commit/e774b06fc2173eb094e2b698a93624a54cd37dff))
* **dns-summary:** improve responsive styles ([#2535](https://github.com/homarr-labs/homarr/issues/2535)) ([7ec6fbc](https://github.com/homarr-labs/homarr/commit/7ec6fbc3765491a810356948a294309ab606bdce))
* **downloads:** improve responsive styles ([#2552](https://github.com/homarr-labs/homarr/issues/2552)) ([d714e53](https://github.com/homarr-labs/homarr/commit/d714e53cfa88da22a6fc75473455d57be7bac497))
* **import:** autofix missing sizes of items with grid-algorithm ([#2522](https://github.com/homarr-labs/homarr/issues/2522)) ([d410af3](https://github.com/homarr-labs/homarr/commit/d410af34029a43e6e11cd766f55c634b00eb8fa2))
* **indexer-manager:** improve responsive styles ([#2541](https://github.com/homarr-labs/homarr/issues/2541)) ([4472c04](https://github.com/homarr-labs/homarr/commit/4472c04967f0a3799507785b02f96a84c9626465))
* **media-request-list:** improve responsive styles ([#2543](https://github.com/homarr-labs/homarr/issues/2543)) ([9e48f43](https://github.com/homarr-labs/homarr/commit/9e48f438b4550f542130651ea7dccccc36b59da8))
* **media-request-stats:** improve responsive styles ([#2544](https://github.com/homarr-labs/homarr/issues/2544)) ([d584ade](https://github.com/homarr-labs/homarr/commit/d584ade8f4a788b284071cb9d17b6d8b606098c8))
* **media-server:** improve responsive styles ([#2548](https://github.com/homarr-labs/homarr/issues/2548)) ([82528db](https://github.com/homarr-labs/homarr/commit/82528dbd961b21682d71b104b22804391b6c7d08))
* **media-transcoding:** improve responsive styles ([#2550](https://github.com/homarr-labs/homarr/issues/2550)) ([8f8d788](https://github.com/homarr-labs/homarr/commit/8f8d7884a9484aa8e73f4ff114e58df78a8bb470))
* **minecraft-status:** wrong api path for bedrock ([#2551](https://github.com/homarr-labs/homarr/issues/2551)) ([2f80c09](https://github.com/homarr-labs/homarr/commit/2f80c096a7e25b1a223336644f40a56311e1c7a8))
* **notebook:** css for checkboxes not working ([#2570](https://github.com/homarr-labs/homarr/issues/2570)) ([a53e7aa](https://github.com/homarr-labs/homarr/commit/a53e7aaee5207ab563b6e0144f3154db917f7da1))
* **smart-home:** improve responsive styles ([#2540](https://github.com/homarr-labs/homarr/issues/2540)) ([0b07f22](https://github.com/homarr-labs/homarr/commit/0b07f227ee72988fe1cbd37a9a6a8751b942a087))
* **system-health:** improve responsive styles ([#2566](https://github.com/homarr-labs/homarr/issues/2566)) ([268daee](https://github.com/homarr-labs/homarr/commit/268daee4a6e90052a19b9d2426c2cf8b2c8a0c00))
## [1.10.0](https://github.com/homarr-labs/homarr/compare/v1.9.0...v1.10.0) (2025-03-07)
### Features
* remove cqmin system ([#2407](https://github.com/homarr-labs/homarr/issues/2407)) ([37d4714](https://github.com/homarr-labs/homarr/commit/37d471457a0a2b10112b67c02923f63de479e617))
### Bug Fixes
* **deps:** update dependency eslint-config-prettier to ^10.1.1 ([#2524](https://github.com/homarr-labs/homarr/issues/2524)) ([4721a97](https://github.com/homarr-labs/homarr/commit/4721a97094ae1181216923c7fef7a29c343f882b))
* **deps:** update dependency ioredis to v5.6.0 ([#2509](https://github.com/homarr-labs/homarr/issues/2509)) ([e4a3922](https://github.com/homarr-labs/homarr/commit/e4a39223a33d4bfccb1e9b4e2c30de1376879a1d))
* **deps:** update dependency mysql2 to v3.13.0 ([#2516](https://github.com/homarr-labs/homarr/issues/2516)) ([67c739c](https://github.com/homarr-labs/homarr/commit/67c739c35bcb2d537a349f0ebff080eac67e93b5))
* **deps:** update tanstack-query monorepo to ^5.67.2 ([#2525](https://github.com/homarr-labs/homarr/issues/2525)) ([a572aae](https://github.com/homarr-labs/homarr/commit/a572aae887142a7e601f70dcc601bf6335e37c17))
* **pi-hole:** wrong fetch used in factory ([#2527](https://github.com/homarr-labs/homarr/issues/2527)) ([9881577](https://github.com/homarr-labs/homarr/commit/9881577f47fbeacf861dd564d57fc6d7c469d27b))
## [1.9.0](https://github.com/homarr-labs/homarr/compare/v1.8.0...v1.9.0) (2025-03-05)
### Features
* add sigterm support ([#2472](https://github.com/homarr-labs/homarr/issues/2472)) ([a5e0e8c](https://github.com/homarr-labs/homarr/commit/a5e0e8c1296ebfbe46c88fbb152b5d0049db349d))
* added bordercolor option for dynamic section ([#2334](https://github.com/homarr-labs/homarr/issues/2334)) ([7dfb108](https://github.com/homarr-labs/homarr/commit/7dfb108a56e38c32e712b82d1e1bd65a5c15722b))
* **integration:** add emby integration ([#2466](https://github.com/homarr-labs/homarr/issues/2466)) ([7dfc364](https://github.com/homarr-labs/homarr/commit/7dfc3646b709e6bb1fc7ec11336024c7eff1f342))
* **media-request:** show request status ([#2465](https://github.com/homarr-labs/homarr/issues/2465)) ([80c2040](https://github.com/homarr-labs/homarr/commit/80c2040b1345b0a60030aa8879442b937863216f))
* **pihole:** add support for v6 ([#2448](https://github.com/homarr-labs/homarr/issues/2448)) ([3804d53](https://github.com/homarr-labs/homarr/commit/3804d530ec28c90b6ab1fa0f709468e2075afa28))
* use fetch with trusted certificates for oidc ([#2412](https://github.com/homarr-labs/homarr/issues/2412)) ([6fad48f](https://github.com/homarr-labs/homarr/commit/6fad48f65ad7cbb927fd80de49930a8256110331))
### Bug Fixes
* affix hides pagination on mobile ([#2491](https://github.com/homarr-labs/homarr/issues/2491)) ([604a05f](https://github.com/homarr-labs/homarr/commit/604a05f9d528b7d89b09f4f7982921963ba0fb90))
* **boards:** case-sensitive board names in url ([#2454](https://github.com/homarr-labs/homarr/issues/2454)) ([c0e3544](https://github.com/homarr-labs/homarr/commit/c0e354428af2c69bf7638911320888f049ec0659))
* **deps:** update dependency @tabler/icons-react to ^3.31.0 ([#2502](https://github.com/homarr-labs/homarr/issues/2502)) ([478aae6](https://github.com/homarr-labs/homarr/commit/478aae6cd496ef81e3036d8f2a5b6959b7fea12e))
* **deps:** update dependency prettier to ^3.5.3 ([#2485](https://github.com/homarr-labs/homarr/issues/2485)) ([49b0f96](https://github.com/homarr-labs/homarr/commit/49b0f962e0b316bbed599d77d97be927aac252da))
* **deps:** update dependency typescript-eslint to ^8.26.0 ([#2488](https://github.com/homarr-labs/homarr/issues/2488)) ([21f3a5a](https://github.com/homarr-labs/homarr/commit/21f3a5a408ab45dbf7d92162703e74b9e60aff10))
* **deps:** update mantine monorepo to ^7.17.1 ([#2462](https://github.com/homarr-labs/homarr/issues/2462)) ([d9ef1b0](https://github.com/homarr-labs/homarr/commit/d9ef1b04706a3435d4500db2f2966a28db900d9d))
* **deps:** update tanstack-query monorepo to ^5.67.0 ([#2486](https://github.com/homarr-labs/homarr/issues/2486)) ([bad07cb](https://github.com/homarr-labs/homarr/commit/bad07cbf251ab64afe99390bcb687d2f58e8fdc7))
* **deps:** update tanstack-query monorepo to ^5.67.1 ([#2487](https://github.com/homarr-labs/homarr/issues/2487)) ([6135b59](https://github.com/homarr-labs/homarr/commit/6135b59b7d24029eaf24ae2a2b94b5cbc822242a))
* docker add to homarr layout overflow ([#2441](https://github.com/homarr-labs/homarr/issues/2441)) ([a3999bc](https://github.com/homarr-labs/homarr/commit/a3999bcf521d4d339282701b4734b6cd352c9582))
* **integration:** store omv session in redis ([#2467](https://github.com/homarr-labs/homarr/issues/2467)) ([b3e4f30](https://github.com/homarr-labs/homarr/commit/b3e4f3031296ffc69d914f542f95895a449ce2c7))
* **logs:** add special case for axios error to prevent huge error messages ([#2468](https://github.com/homarr-labs/homarr/issues/2468)) ([9eb7663](https://github.com/homarr-labs/homarr/commit/9eb76634d07b7bf5ff28062714c44e150591d75d))
* **media-request:** inconsistent sorting and reordering ([#2464](https://github.com/homarr-labs/homarr/issues/2464)) ([43619e0](https://github.com/homarr-labs/homarr/commit/43619e0cc0311ca8f26a4fdbc0ccb7fae79c3514))
* **old-import:** default logo and favicon not replaced ([#2456](https://github.com/homarr-labs/homarr/issues/2456)) ([788304a](https://github.com/homarr-labs/homarr/commit/788304adfbe3c6c9696758e9ad42bca9d9b86290))
## [1.8.0](https://github.com/homarr-labs/homarr/compare/v1.7.0...v1.8.0) (2025-02-28)
### Features
* add app ping url ([#2380](https://github.com/homarr-labs/homarr/issues/2380)) ([fb467ac](https://github.com/homarr-labs/homarr/commit/fb467ac16553d3c498770a531cf77b9f2c7c0a9e))
* **boards:** add responsive layout system ([#2271](https://github.com/homarr-labs/homarr/issues/2271)) ([7761dc2](https://github.com/homarr-labs/homarr/commit/7761dc29c809b28cc8275dcabf77c453cea3621c))
### Bug Fixes
* await params for board metadata ([#2406](https://github.com/homarr-labs/homarr/issues/2406)) ([2085b5e](https://github.com/homarr-labs/homarr/commit/2085b5ece24f661086c4896a6ecfbff61de1b7d4))
* **boards:** add scrollarea to board-select ([#2409](https://github.com/homarr-labs/homarr/issues/2409)) ([508f9af](https://github.com/homarr-labs/homarr/commit/508f9afeb542d09d06fc34f06ac68cf732011620))
* chinese traditional locale ([#2440](https://github.com/homarr-labs/homarr/issues/2440)) ([50367eb](https://github.com/homarr-labs/homarr/commit/50367eb2f5ae9cb6b736197692b3f555e07aca59))
* **deps:** downgrade to next 15.1.7 cause of turbopack crash with 15.2.0 and above ([#2438](https://github.com/homarr-labs/homarr/issues/2438)) ([fdd91f5](https://github.com/homarr-labs/homarr/commit/fdd91f585d1c0c66a6c28c6d1e374bdd9fdcb787))
* **deps:** update dependency @auth/core to ^0.38.0 ([#2434](https://github.com/homarr-labs/homarr/issues/2434)) ([8c1308c](https://github.com/homarr-labs/homarr/commit/8c1308c97f011336c2a813e92e7cefa195277994))
* **deps:** update dependency @auth/drizzle-adapter to ^1.8.0 ([#2435](https://github.com/homarr-labs/homarr/issues/2435)) ([b2cc97e](https://github.com/homarr-labs/homarr/commit/b2cc97e316976e74df8136a7da53a3fae78f815b))
* **deps:** update dependency drizzle-kit to ^0.30.5 ([#2423](https://github.com/homarr-labs/homarr/issues/2423)) ([3b830ae](https://github.com/homarr-labs/homarr/commit/3b830ae098c290aaa15356cae5ec2fe8cb618d9f))
* **deps:** update dependency drizzle-orm to ^0.40.0 ([#2425](https://github.com/homarr-labs/homarr/issues/2425)) ([faf7322](https://github.com/homarr-labs/homarr/commit/faf7322bcb94a61dbb2b3295cc4a4eca52484d74))
* **deps:** update dependency eslint-config-prettier to ^10.0.2 ([#2427](https://github.com/homarr-labs/homarr/issues/2427)) ([c2d6e2e](https://github.com/homarr-labs/homarr/commit/c2d6e2efcf06e97c04bddc2d821c77ad034426b8))
* **deps:** update dependency eslint-plugin-react-hooks to ^5.2.0 ([#2449](https://github.com/homarr-labs/homarr/issues/2449)) ([a88c1ba](https://github.com/homarr-labs/homarr/commit/a88c1ba4401bbe6317ccde11cff9a057bfa53e26))
* **deps:** update dependency prettier to ^3.5.2 ([#2399](https://github.com/homarr-labs/homarr/issues/2399)) ([86e778d](https://github.com/homarr-labs/homarr/commit/86e778db1ee081288b4174f6b52fcc44a0bbc1e0))
* **deps:** update dependency sass to ^1.85.1 ([#2418](https://github.com/homarr-labs/homarr/issues/2418)) ([a9a37af](https://github.com/homarr-labs/homarr/commit/a9a37afd441ad148a42432c24a9c7e6acf804c89))
* **deps:** update dependency swagger-ui-react to ^5.20.0 ([#2436](https://github.com/homarr-labs/homarr/issues/2436)) ([add9170](https://github.com/homarr-labs/homarr/commit/add91701de30eaeb61efe3295307756e998703a9))
* **deps:** update dependency typescript-eslint to ^8.25.0 ([#2413](https://github.com/homarr-labs/homarr/issues/2413)) ([593c50b](https://github.com/homarr-labs/homarr/commit/593c50bb8f803ecbda8e6d0c4a082e019cc56352))
* **deps:** update dependency undici to v7.4.0 ([#2445](https://github.com/homarr-labs/homarr/issues/2445)) ([06ba0f0](https://github.com/homarr-labs/homarr/commit/06ba0f0e9f6da9c22ef531e41811a89c8c5039a8))
* **deps:** update nextjs monorepo to ^15.2.0 ([#2428](https://github.com/homarr-labs/homarr/issues/2428)) ([d6939e4](https://github.com/homarr-labs/homarr/commit/d6939e4a6daf7fbe0095ae4028d33189c5866fb2))
* **deps:** update tanstack-query monorepo to ^5.66.10 ([#2443](https://github.com/homarr-labs/homarr/issues/2443)) ([4483dc8](https://github.com/homarr-labs/homarr/commit/4483dc8bcd062f531badd94ba872cf42a17491df))
* **deps:** update tanstack-query monorepo to ^5.66.11 ([#2447](https://github.com/homarr-labs/homarr/issues/2447)) ([5537f95](https://github.com/homarr-labs/homarr/commit/5537f95b85b1ae56a35d7b529907ebe22d0b1ae6))
* **deps:** update turbo monorepo to ^2.4.3 ([#2422](https://github.com/homarr-labs/homarr/issues/2422)) ([874414f](https://github.com/homarr-labs/homarr/commit/874414fc4fc1130502abc267116ad109dab11efe))
* **deps:** update turbo monorepo to ^2.4.4 ([#2424](https://github.com/homarr-labs/homarr/issues/2424)) ([a6f9199](https://github.com/homarr-labs/homarr/commit/a6f91998c3a8192eaa93b57a74b6dfc8f3fdc13a))
* omv invalid temperature when not available ([#2322](https://github.com/homarr-labs/homarr/issues/2322)) ([5dc5d9e](https://github.com/homarr-labs/homarr/commit/5dc5d9e04ab747655276494d70557b45fed87b2c))
* update checker logs incorrectly ([#2402](https://github.com/homarr-labs/homarr/issues/2402)) ([c5107b2](https://github.com/homarr-labs/homarr/commit/c5107b2b67cad73808dcbae6bde633ac1a7eb2b5))
## [1.7.0](https://github.com/homarr-labs/homarr/compare/v1.6.0...v1.7.0) (2025-02-21)
### Features
+1 -1
View File
@@ -1,4 +1,4 @@
FROM node:22.14.0-alpine AS base
FROM node:22.15.0-alpine AS base
FROM base AS builder
RUN apk add --no-cache libc6-compat
+6 -1
View File
@@ -10,7 +10,12 @@ import MillionLint from "@million/lint";
import createNextIntlPlugin from "next-intl/plugin";
// Package path does not work... so we need to use relative path
const withNextIntl = createNextIntlPlugin("../../packages/translation/src/request.ts");
const withNextIntl = createNextIntlPlugin({
experimental: {
createMessagesDeclaration: "../../packages/translation/src/lang/en.json",
},
requestConfig: "../../packages/translation/src/request.ts",
});
interface WebpackConfig {
module: {
+31 -31
View File
@@ -6,7 +6,7 @@
"scripts": {
"build": "pnpm with-env next build",
"clean": "git clean -xdf .next .turbo node_modules",
"dev": "pnpm with-env next dev --turbopack",
"dev": "pnpm with-env next dev",
"format": "prettier --check . --ignore-path ../../.gitignore",
"lint": "eslint",
"start": "pnpm with-env next start",
@@ -48,59 +48,59 @@
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0",
"@mantine/colors-generator": "^7.17.0",
"@mantine/core": "^7.17.0",
"@mantine/dropzone": "^7.17.0",
"@mantine/hooks": "^7.17.0",
"@mantine/modals": "^7.17.0",
"@mantine/tiptap": "^7.17.0",
"@mantine/colors-generator": "^7.17.7",
"@mantine/core": "^7.17.7",
"@mantine/dropzone": "^7.17.7",
"@mantine/hooks": "^7.17.7",
"@mantine/modals": "^7.17.7",
"@mantine/tiptap": "^7.17.7",
"@million/lint": "1.0.14",
"@tabler/icons-react": "^3.30.0",
"@tanstack/react-query": "^5.66.9",
"@tanstack/react-query-devtools": "^5.66.9",
"@tanstack/react-query-next-experimental": "^5.66.9",
"@trpc/client": "next",
"@trpc/next": "next",
"@trpc/react-query": "next",
"@trpc/server": "next",
"@tabler/icons-react": "^3.31.0",
"@tanstack/react-query": "^5.75.1",
"@tanstack/react-query-devtools": "^5.75.1",
"@tanstack/react-query-next-experimental": "^5.75.1",
"@trpc/client": "^11.1.2",
"@trpc/next": "^11.1.2",
"@trpc/react-query": "^11.1.2",
"@trpc/server": "^11.1.2",
"@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "^5.5.0",
"chroma-js": "^3.1.2",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"dotenv": "^16.4.7",
"dotenv": "^16.5.0",
"flag-icons": "^7.3.2",
"glob": "^11.0.1",
"jotai": "^2.12.1",
"glob": "^11.0.2",
"jotai": "^2.12.3",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.1.7",
"next": "15.3.1",
"postcss-preset-mantine": "^1.17.0",
"prismjs": "^1.29.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"prismjs": "^1.30.0",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-error-boundary": "^5.0.0",
"react-simple-code-editor": "^0.14.1",
"sass": "^1.85.0",
"sass": "^1.87.0",
"superjson": "2.2.2",
"swagger-ui-react": "^5.19.0",
"swagger-ui-react": "^5.21.0",
"use-deep-compare-effect": "^1.8.1",
"zod": "^3.24.2"
"zod": "^3.24.3"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/chroma-js": "3.1.1",
"@types/node": "^22.13.5",
"@types/node": "^22.15.3",
"@types/prismjs": "^1.26.5",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
"@types/react": "19.1.2",
"@types/react-dom": "19.1.3",
"@types/swagger-ui-react": "^5.18.0",
"concurrently": "^9.1.2",
"eslint": "^9.21.0",
"eslint": "^9.25.1",
"node-loader": "^2.1.0",
"prettier": "^3.5.2",
"typescript": "^5.7.3"
"prettier": "^3.5.3",
"typescript": "^5.8.3"
}
}
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 139.3 512.2 233.5"><path d="M256 139.3c-53 0-97.9 35.8-112.1 84.4-12.2-25.5-38.2-43.4-68.2-43.4C34.2 180.2 0 214.4 0 256s34.2 75.8 75.8 75.8c30 0 55.9-17.9 68.2-43.4 14.1 48.6 59.1 84.4 112.1 84.4S354 337 368.2 288.4c12.2 25.5 38.2 43.4 68.2 43.4 41.6 0 75.8-34.2 75.8-75.8s-34.2-75.8-75.8-75.8c-30 0-55.9 17.9-68.2 43.4-14.3-48.5-59.2-84.3-112.2-84.3m0 45c39.9 0 71.7 31.8 71.7 71.7s-31.8 71.7-71.7 71.7-71.7-31.8-71.7-71.7 31.8-71.7 71.7-71.7m-180.2 41c17.2 0 30.7 13.5 30.7 30.7S93 286.7 75.8 286.7 45.1 273.2 45.1 256s13.4-30.7 30.7-30.7m360.4 0c17.2 0 30.7 13.5 30.7 30.7s-13.5 30.7-30.7 30.7-30.7-13.5-30.7-30.7 13.5-30.7 30.7-30.7" style="fill:#3784c9"/></svg>

After

Width:  |  Height:  |  Size: 739 B

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="cm.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-2.090004"
inkscape:cy="33.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="771"
inkscape:window-x="1"
inkscape:window-y="0"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<g
id="g3349"
transform="translate(0.11778981,0.45794291)">
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 8.236948,6.2914262 5.825001,0"
id="path876" />
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 5.723058,6.2914262 1.45834,0"
id="path880" />
<a
id="a3346">
<path
id="path884"
d="m 10.353619,8.4080928 3.70833,0"
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:export-xdpi="376.57999"
inkscape:export-ydpi="376.57999" />
</a>
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 7.839728,8.4080928 1.4583305,0"
id="path888" />
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 10.353619,10.52476 3.70833,0"
id="path892" />
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 7.839728,10.52476 1.4583305,0"
id="path896" />
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 8.236948,12.641428 5.825001,0"
id="path900" />
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 5.723058,12.641428 1.45834,0"
id="path904" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.6 KiB

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="ing.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-2.090004"
inkscape:cy="28.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="775"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<path
id="path7709"
pointer-events="none"
d="m 12.75799,13.997178 -2.270701,0 -4.9209009,-6.1558617 -1.42366,0 0,-2.0149069 2.31473,0 4.9230119,6.1558536 1.37752,0 0,-1.593474 3.119869,2.599882 -3.119869,2.601983 z m -2.47616,-4.7552751 1.09864,-1.3754256 1.37752,0 0,1.593475 3.119869,-2.5998829 -3.119869,-2.601983 0,1.593483 -2.270701,0 -1.4571904,1.8241102 z m -3.5979219,1.3649431 -1.11752,1.400578 -1.42366,0 0,2.014915 2.31473,0 1.4781699,-1.849278 z"
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.20966817" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="ns.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-2.090004"
inkscape:cy="23.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="775"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<rect
y="6.5793304"
x="6.1734986"
height="6.6900792"
width="7.6735892"
id="rect8790"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.40000001;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:0.80000001, 0.4;stroke-dashoffset:3.44000006;stroke-opacity:1" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.0 KiB

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="node.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="16.847496"
inkscape:cy="33.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="775"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<path
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccccc"
id="path1994"
d="M 9.9921803,5.0101759 C 9.8538505,5.0057759 5.9970805,6.902049 5.9466504,6.999295 c -0.12117,0.233682 -0.9989,4.281827 -0.94731,4.369074 0.03,0.05065 0.66219,0.851861 1.40458,1.780327 l 1.3498201,1.688014 2.2211901,9.31e-4 2.2216404,9.31e-4 1.41321,-1.765731 1.41365,-1.765228 -0.49479,-2.1685759 C 14.256441,7.946271 14.012981,6.950423 13.988111,6.926433 13.918611,6.859553 10.067151,5.0126389 9.9921803,5.0102179 Z m 0.1961407,0.947753 0.90893,0.2635771 -0.90893,0.263576 -0.9089209,-0.263576 z m -0.9089209,0.36452 0.8511209,0.2532261 -0.004,1.183289 -0.8468109,-0.469347 z m 1.8178509,0 0,0.9671681 -0.84679,0.469347 -0.004,-1.183289 z M 8.8997705,7.937127 9.8087101,8.2007027 8.8997705,8.4642797 7.9908504,8.2007027 Z m 2.2087005,0 0.90894,0.2635757 -0.90894,0.263577 -0.90893,-0.263577 z m -3.1176206,0.3645197 0.8511202,0.252792 -0.004,1.1832908 -0.8468199,-0.468915 z m 1.8178597,0 0,0.9671678 -0.8468098,0.468915 -0.004,-1.1832908 z m 0.3908309,0 0.85113,0.252792 -0.004,1.1832908 -0.84682,-0.468915 z m 1.81787,0 0,0.9671678 -0.84682,0.468915 -0.004,-1.1832908 z m -3.4496605,1.515028 c 0.2706299,0.0096 0.0611,0.2819093 0.3684101,0.4279353 0.3277495,0.155764 0.3953995,-0.235354 0.6013395,0.06341 0.20599,0.298766 -0.18339,0.223239 -0.15443,0.584957 0.029,0.361718 0.40165,0.224858 0.24589,0.552606 -0.15575,0.327746 -0.28532,-0.04764 -0.5840895,0.158317 -0.2987401,0.205957 0.006,0.460208 -0.35546,0.489192 -0.3617401,0.02898 -0.1015001,-0.270447 -0.42924,-0.426208 -0.32775,-0.155765 -0.3953801,0.234921 -0.6013402,-0.06385 -0.2059599,-0.298767 0.1838299,-0.22281 0.15485,-0.584528 -0.029,-0.361718 -0.4016499,-0.224859 -0.24587,-0.552604 0.1557501,-0.327749 0.2848801,0.04764 0.5836502,-0.15832 0.2987898,-0.205956 -0.006,-0.4602083 0.3559099,-0.4891903 0.022499,-0.0018 0.0424,-0.0023 0.0604,-0.0018 z m 2.3359605,0.3627943 c 0.48335,0.01358 0.0146,0.467218 0.45596,0.664766 0.44144,0.197548 0.46714,-0.454103 0.79937,-0.102669 0.33221,0.351432 -0.31997,0.34064 -0.14753,0.792455 0.17243,0.451813 0.65163,0.0092 0.63802,0.49264 -0.0137,0.483411 -0.46723,0.01456 -0.66477,0.455977 -0.19755,0.441412 0.4541,0.467143 0.10266,0.799357 -0.35141,0.332212 -0.34021,-0.319974 -0.79202,-0.147534 -0.45183,0.172437 -0.009,0.65161 -0.49265,0.638019 -0.48339,-0.01358 -0.0146,-0.467216 -0.45596,-0.664764 -0.4414105,-0.197551 -0.4675805,0.454102 -0.7997909,0.102669 -0.3322097,-0.351431 0.3199804,-0.340209 0.14754,-0.792025 -0.17245,-0.451815 -0.6516296,-0.0092 -0.6380295,-0.492642 0.013699,-0.483408 0.4672095,-0.01499 0.6647795,-0.456405 0.1975204,-0.441414 -0.45411,-0.467143 -0.10269,-0.799357 0.3514505,-0.332213 0.3406505,0.319971 0.7924609,0.147534 0.45184,-0.17244 0.009,-0.651611 0.49265,-0.638021 z m -2.3148207,0.253655 c -0.2936499,9e-5 -0.5316098,0.238249 -0.5314498,0.531898 7.99e-5,0.293481 0.2379701,0.531377 0.5314498,0.531467 0.2936602,1.59e-4 0.5318202,-0.23781 0.5319,-0.531467 1.601e-4,-0.293825 -0.2380699,-0.532057 -0.5319,-0.531898 z m 2.2643607,0.480564 c -0.58689,-1.96e-4 -1.0627109,0.475614 -1.0625209,1.062502 5e-5,0.586719 0.4758009,1.062267 1.0625209,1.062071 0.58654,-5.8e-5 1.06201,-0.475531 1.06206,-1.062071 1.9e-4,-0.586708 -0.47535,-1.062444 -1.06206,-1.062502 z"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#eeeeee;stroke-width:0;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:11.23642349;stroke-opacity:1"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

@@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="pod.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-2.090004"
inkscape:cy="33.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="775"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<g
id="g3341"
transform="translate(0.12766661,0.35147801)">
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="M 6.2617914,7.036086 9.8826317,5.986087 13.503462,7.036086 9.8826317,8.086087 Z"
id="path910" />
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 6.2617914,7.43817 0,3.852778 3.3736103,1.868749 0.0167,-4.713193 z"
id="path912" />
<path
inkscape:export-ydpi="376.57999"
inkscape:export-xdpi="376.57999"
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 13.503462,7.43817 0,3.852778 -3.37361,1.868749 -0.0167,-4.713193 z"
id="path914" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="secret.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-2.090004"
inkscape:cy="28.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="775"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<g
id="g3347"
transform="translate(0.05710921,0.77487342)">
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 10.414299,8.0912253 3.708331,0"
id="path922" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79400003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 8.2976282,5.9745582 5.8250018,0"
id="path930" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 5.7837382,5.9745582 1.45834,0"
id="path934" />
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:#326ce5;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 7.7183782,8.4321603 0,0 c 0,-1.1667021 1.0110897,-2.1125011 2.2583305,-2.1125011 1.2472403,0 2.2583303,0.945799 2.2583303,2.1125011 l -1.05624,0 0,0 c 0,-0.583351 -0.5382,-1.0562501 -1.2020903,-1.0562501 -0.6638904,0 -1.2020808,0.4728991 -1.2020808,1.0562501 z"
id="path936" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 10.414299,10.207893 3.708331,0"
id="path942" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 8.2976282,12.32456 5.8250018,0"
id="path950" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.79374999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 5.7837382,12.32456 1.45834,0"
id="path954" />
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:#326ce5;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 7.1622182,8.3691063 5.6166608,0 0,3.6583337 -5.6166608,0 z"
id="path956" />
<circle
r="0.55515254"
cy="10.198272"
cx="9.9705448"
id="path7280"
style="opacity:1;fill:#326ce5;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.26478875;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:0.52957746, 0.26478873;stroke-dashoffset:5.01860619;stroke-opacity:1" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.5 KiB

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="svc.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-2.090004"
inkscape:cy="28.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="775"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<g
id="g3345"
transform="translate(0.09238801,0.66897746)">
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 4.4949896,11.260826 2.9083311,0 0,2.041667 -2.9083311,0 z"
id="path964" />
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 8.4637407,11.260826 2.9083303,0 0,2.041667 -2.9083303,0 z"
id="path966" />
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 12.432491,11.260826 2.90833,0 0,2.041667 -2.90833,0 z"
id="path968" />
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 7.6137407,5.2082921 4.6083303,0 0,2.041667 -4.6083303,0 z"
id="path970" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 9.9179005,7.2499601 0,2.005449 -3.966671,0 0,2.0028859"
id="path978" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.52899998;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 9.9179005,7.2499601 0,2.005449 3.9666705,0 0,2.0028859"
id="path986" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 9.9095538,7.2512251 0,2.005449 0.0167,0 0,2.0028859"
id="path982" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="18.035334mm"
height="17.500378mm"
viewBox="0 0 18.035334 17.500378"
version="1.1"
id="svg13826"
inkscape:version="0.91 r13725"
sodipodi:docname="pv.svg">
<defs
id="defs13820" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="8"
inkscape:cx="-12.090004"
inkscape:cy="28.752239"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="775"
inkscape:window-x="0"
inkscape:window-y="1"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0" />
<metadata
id="metadata13823">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-0.99262638,-1.174181)">
<g
id="g70"
transform="matrix(1.0148887,0,0,1.0148887,16.902146,-2.698726)">
<path
inkscape:export-ydpi="250.55"
inkscape:export-xdpi="250.55"
inkscape:export-filename="new.png"
inkscape:connector-curvature="0"
id="path3055"
d="m -6.8492015,4.2724668 a 1.1191255,1.1099671 0 0 0 -0.4288818,0.1085303 l -5.8524037,2.7963394 a 1.1191255,1.1099671 0 0 0 -0.605524,0.7529759 l -1.443828,6.2812846 a 1.1191255,1.1099671 0 0 0 0.151943,0.851028 1.1191255,1.1099671 0 0 0 0.06362,0.08832 l 4.0508,5.036555 a 1.1191255,1.1099671 0 0 0 0.874979,0.417654 l 6.4961011,-0.0015 a 1.1191255,1.1099671 0 0 0 0.8749788,-0.416906 L 1.3818872,15.149453 A 1.1191255,1.1099671 0 0 0 1.5981986,14.210104 L 0.15212657,7.9288154 A 1.1191255,1.1099671 0 0 0 -0.45339794,7.1758396 L -6.3065496,4.3809971 A 1.1191255,1.1099671 0 0 0 -6.8492015,4.2724668 Z"
style="fill:#326ce5;fill-opacity:1;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path3054-2-9"
d="M -6.8523435,3.8176372 A 1.1814304,1.171762 0 0 0 -7.3044284,3.932904 l -6.1787426,2.9512758 a 1.1814304,1.171762 0 0 0 -0.639206,0.794891 l -1.523915,6.6308282 a 1.1814304,1.171762 0 0 0 0.160175,0.89893 1.1814304,1.171762 0 0 0 0.06736,0.09281 l 4.276094,5.317236 a 1.1814304,1.171762 0 0 0 0.92363,0.440858 l 6.8576188,-0.0015 a 1.1814304,1.171762 0 0 0 0.9236308,-0.44011 l 4.2745966,-5.317985 a 1.1814304,1.171762 0 0 0 0.228288,-0.990993 L 0.53894439,7.6775738 A 1.1814304,1.171762 0 0 0 -0.10026101,6.8834313 L -6.2790037,3.9321555 A 1.1814304,1.171762 0 0 0 -6.8523435,3.8176372 Z m 0.00299,0.4550789 a 1.1191255,1.1099671 0 0 1 0.5426517,0.1085303 l 5.85315169,2.7948425 A 1.1191255,1.1099671 0 0 1 0.15197811,7.9290648 L 1.598051,14.21035 a 1.1191255,1.1099671 0 0 1 -0.2163123,0.939348 l -4.0493032,5.037304 a 1.1191255,1.1099671 0 0 1 -0.8749789,0.416906 l -6.4961006,0.0015 a 1.1191255,1.1099671 0 0 1 -0.874979,-0.417652 l -4.0508,-5.036554 a 1.1191255,1.1099671 0 0 1 -0.06362,-0.08832 1.1191255,1.1099671 0 0 1 -0.151942,-0.851028 l 1.443827,-6.2812853 a 1.1191255,1.1099671 0 0 1 0.605524,-0.7529758 l 5.8524036,-2.7963395 a 1.1191255,1.1099671 0 0 1 0.4288819,-0.1085303 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;marker:none;enable-background:accumulate"
inkscape:connector-curvature="0" />
</g>
<g
id="g3341"
transform="translate(-0.18983289,0.49258906)">
<path
style="fill:#ffffff;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 5.5709614,7.9105849 0,0 c 0,0.621121 2.0725401,1.124639 4.6291706,1.124639 2.556609,0 4.629159,-0.503518 4.629159,-1.124639 l 0,3.0423911 c 0,0.62112 -2.07255,1.124638 -4.629159,1.124638 -2.5566305,0 -4.6291706,-0.503518 -4.6291706,-1.124638 z"
id="path1114" />
<path
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:square;stroke-miterlimit:10"
inkscape:connector-curvature="0"
d="m 5.5709614,7.9105849 0,0 c 0,-0.621119 2.0725401,-1.124637 4.6291706,-1.124637 2.556609,0 4.629159,0.503518 4.629159,1.124637 l 0,0 c 0,0.621121 -2.07255,1.124639 -4.629159,1.124639 -2.5566305,0 -4.6291706,-0.503518 -4.6291706,-1.124639 z"
id="path1116" />
<path
style="fill:none;fill-rule:evenodd;stroke:#326ce5;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 14.829291,7.9105849 0,0 c 0,0.621121 -2.07255,1.124639 -4.629159,1.124639 -2.5566205,0 -4.6291706,-0.503518 -4.6291706,-1.124639 l 0,0 c 0,-0.621119 2.0725501,-1.124637 4.6291706,-1.124637 2.556609,0 4.629159,0.503518 4.629159,1.124637 l 0,3.0423911 c 0,0.62112 -2.07255,1.124638 -4.629159,1.124638 -2.5566205,0 -4.6291706,-0.503518 -4.6291706,-1.124638 l 0,-3.0423911"
id="path1120" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

@@ -7,11 +7,11 @@ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
import { ReactQueryStreamedHydration } from "@tanstack/react-query-next-experimental";
import {
createWSClient,
httpBatchStreamLink,
httpLink,
isNonJsonSerializable,
loggerLink,
splitLink,
unstable_httpBatchStreamLink,
wsLink,
} from "@trpc/client";
import superjson from "superjson";
@@ -90,7 +90,7 @@ export function TRPCReactProvider(props: PropsWithChildren) {
url: getTrpcUrl(),
headers: createHeadersCallbackForSource("nextjs-react (form-data)"),
}),
false: unstable_httpBatchStreamLink({
false: httpBatchStreamLink({
transformer: superjson,
url: getTrpcUrl(),
maxURLLength: 2083, // Suggested by tRPC: https://trpc.io/docs/client/links/httpBatchLink#setting-a-maximum-url-length
@@ -9,7 +9,7 @@ import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
import { CustomPasswordInput } from "@homarr/ui";
import { validation } from "@homarr/validation";
import { userRegistrationSchema } from "@homarr/validation/user";
interface RegistrationFormProps {
invite: {
@@ -22,7 +22,7 @@ export const RegistrationForm = ({ invite }: RegistrationFormProps) => {
const t = useScopedI18n("user");
const router = useRouter();
const { mutate, isPending } = clientApi.user.register.useMutation();
const form = useZodForm(validation.user.registration, {
const form = useZodForm(userRegistrationSchema, {
initialValues: {
username: "",
password: "",
@@ -30,7 +30,7 @@ export const RegistrationForm = ({ invite }: RegistrationFormProps) => {
},
});
const handleSubmit = (values: z.infer<typeof validation.user.registration>) => {
const handleSubmit = (values: z.infer<typeof userRegistrationSchema>) => {
mutate(
{
...values,
@@ -63,7 +63,8 @@ export default async function InviteUsagePage(props: InviteUsagePageProps) {
<RegistrationForm invite={invite} />
</Card>
<Text size="xs" c="gray.5" ta="center">
{t("description", { username: invite.creator.name })}
{/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion */}
{t("description", { username: invite.creator.name! })}
</Text>
</Stack>
</Center>
@@ -2,7 +2,7 @@
import type { PropsWithChildren } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { useRouter, useSearchParams } from "next/navigation";
import { Anchor, Button, Card, Code, Collapse, Divider, PasswordInput, Stack, Text, TextInput } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { z } from "zod";
@@ -13,7 +13,9 @@ import type { useForm } from "@homarr/form";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { userSignInSchema } from "@homarr/validation/user";
type Provider = "credentials" | "ldap" | "oidc";
interface LoginFormProps {
providers: string[];
@@ -22,10 +24,12 @@ interface LoginFormProps {
callbackUrl: string;
}
const extendedValidation = validation.user.signIn.extend({ provider: z.enum(["credentials", "ldap"]) });
const extendedValidation = userSignInSchema.extend({ provider: z.enum(["credentials", "ldap"]) });
export const LoginForm = ({ providers, oidcClientName, isOidcAutoLoginEnabled, callbackUrl }: LoginFormProps) => {
const t = useScopedI18n("user");
const searchParams = useSearchParams();
const isError = searchParams.has("error");
const router = useRouter();
const [isPending, setIsPending] = useState(false);
const form = useZodForm(extendedValidation, {
@@ -39,22 +43,34 @@ export const LoginForm = ({ providers, oidcClientName, isOidcAutoLoginEnabled, c
const credentialInputsVisible = providers.includes("credentials") || providers.includes("ldap");
const onSuccess = useCallback(
async (response: Awaited<ReturnType<typeof signIn>>) => {
if (response && (!response.ok || response.error)) {
async (provider: Provider, response: Awaited<ReturnType<typeof signIn>>) => {
if (!response.ok || response.error) {
// eslint-disable-next-line @typescript-eslint/only-throw-error
throw response.error;
}
if (provider === "oidc") {
if (!response.url) {
showErrorNotification({
title: t("action.login.notification.error.title"),
message: t("action.login.notification.error.message"),
autoClose: 10000,
});
return;
}
router.push(response.url);
return;
}
showSuccessNotification({
title: t("action.login.notification.success.title"),
message: t("action.login.notification.success.message"),
});
// Redirect to the callback URL if the response is defined and comes from a credentials provider (ldap or credentials). oidc is redirected automatically.
if (response) {
await revalidatePathActionAsync("/");
router.push(callbackUrl);
}
await revalidatePathActionAsync("/");
router.push(callbackUrl);
},
[t, router, callbackUrl],
);
@@ -70,14 +86,14 @@ export const LoginForm = ({ providers, oidcClientName, isOidcAutoLoginEnabled, c
}, [t]);
const signInAsync = useCallback(
async (provider: string, options?: Parameters<typeof signIn>[1]) => {
async (provider: Provider, options?: Parameters<typeof signIn>[1]) => {
setIsPending(true);
await signIn(provider, {
...options,
redirect: false,
callbackUrl: new URL(callbackUrl, window.location.href).href,
})
.then(onSuccess)
.then((response) => onSuccess(provider, response))
.catch(onError);
},
[setIsPending, onSuccess, onError, callbackUrl],
@@ -86,11 +102,12 @@ export const LoginForm = ({ providers, oidcClientName, isOidcAutoLoginEnabled, c
const isLoginInProgress = useRef(false);
useEffect(() => {
if (isError) return;
if (isOidcAutoLoginEnabled && !isPending && !isLoginInProgress.current) {
isLoginInProgress.current = true;
void signInAsync("oidc");
}
}, [signInAsync, isOidcAutoLoginEnabled, isPending]);
}, [signInAsync, isOidcAutoLoginEnabled, isPending, isError]);
return (
<Stack gap="xl">
@@ -5,7 +5,7 @@ import { Box, LoadingOverlay, Stack } from "@mantine/core";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { useRequiredBoard } from "@homarr/boards/context";
import { useCurrentLayout, useRequiredBoard } from "@homarr/boards/context";
import { BoardCategorySection } from "~/components/board/sections/category-section";
import { BoardEmptySection } from "~/components/board/sections/empty-section";
@@ -43,6 +43,7 @@ export const useUpdateBoard = () => {
export const ClientBoard = () => {
const board = useRequiredBoard();
const currentLayoutId = useCurrentLayout();
const isReady = useIsBoardReady();
const fullWidthSortedSections = board.sections
@@ -63,9 +64,10 @@ export const ClientBoard = () => {
<Stack ref={ref} h="100%" style={{ visibility: isReady ? "visible" : "hidden" }}>
{fullWidthSortedSections.map((section) =>
section.kind === "empty" ? (
<BoardEmptySection key={section.id} section={section} />
// Unique keys per layout to always reinitialize the gridstack
<BoardEmptySection key={`${currentLayoutId}-${section.id}`} section={section} />
) : (
<BoardCategorySection key={section.id} section={section} />
<BoardCategorySection key={`${currentLayoutId}-${section.id}`} section={section} />
),
)}
</Stack>
@@ -4,16 +4,22 @@ import { TRPCError } from "@trpc/server";
// Placed here because gridstack styles are used for board content
import "~/styles/gridstack.scss";
import { dehydrate, HydrationBoundary } from "@tanstack/react-query";
import { getQueryClient } from "@homarr/api/server";
import { IntegrationProvider } from "@homarr/auth/client";
import { auth } from "@homarr/auth/next";
import { getIntegrationsWithPermissionsAsync } from "@homarr/auth/server";
import { isNullOrWhitespace } from "@homarr/common";
import type { WidgetKind } from "@homarr/definitions";
import { logger } from "@homarr/log";
import { getI18n } from "@homarr/translation/server";
import { prefetchForKindAsync } from "@homarr/widgets/prefetch";
import { createMetaTitle } from "~/metadata";
import { createBoardLayout } from "../_layout-creator";
import type { Board } from "../_types";
import { ClientBoard } from "./_client";
import type { Board, Item } from "../_types";
import { DynamicClientBoard } from "./_dynamic-client";
import { BoardContentHeaderActions } from "./_header-actions";
export type Params = Record<string, unknown>;
@@ -31,19 +37,41 @@ export const createBoardContentPage = <TParams extends Record<string, unknown>>(
getInitialBoardAsync: getInitialBoard,
}),
// eslint-disable-next-line no-restricted-syntax
page: async () => {
page: async ({ params }: { params: Promise<TParams> }) => {
const session = await auth();
const integrations = await getIntegrationsWithPermissionsAsync(session);
const board = await getInitialBoard(await params);
const queryClient = getQueryClient();
// Prefetch item data
const itemsMap = board.items.reduce((acc, item) => {
const existing = acc.get(item.kind);
if (existing) {
existing.push(item);
} else {
acc.set(item.kind, [item]);
}
return acc;
}, new Map<WidgetKind, Item[]>());
for (const [kind, items] of itemsMap) {
await prefetchForKindAsync(kind, queryClient, items).catch((error) => {
logger.error(new Error("Failed to prefetch widget", { cause: error }));
});
}
return (
<IntegrationProvider integrations={integrations}>
<ClientBoard />
</IntegrationProvider>
<HydrationBoundary state={dehydrate(queryClient)}>
<IntegrationProvider integrations={integrations}>
<DynamicClientBoard />
</IntegrationProvider>
</HydrationBoundary>
);
},
generateMetadataAsync: async ({ params }: { params: TParams }): Promise<Metadata> => {
generateMetadataAsync: async ({ params }: { params: Promise<TParams> }): Promise<Metadata> => {
try {
const board = await getInitialBoard(params);
const board = await getInitialBoard(await params);
const t = await getI18n();
return {
@@ -0,0 +1,7 @@
"use client";
import dynamic from "next/dynamic";
export const DynamicClientBoard = dynamic(() => import("./_client").then((mod) => mod.ClientBoard), {
ssr: false,
});
@@ -4,7 +4,7 @@ import type { MouseEvent } from "react";
import { useCallback, useEffect } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Group, Menu } from "@mantine/core";
import { Group, Menu, ScrollArea } from "@mantine/core";
import { useHotkeys } from "@mantine/hooks";
import {
IconBox,
@@ -25,9 +25,11 @@ import { useEditMode } from "@homarr/boards/edit-mode";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { env } from "@homarr/common/env";
import { useConfirmModal, useModalAction } from "@homarr/modals";
import { AppSelectModal } from "@homarr/modals-collection";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { useItemActions } from "~/components/board/items/item-actions";
import { ItemSelectModal } from "~/components/board/items/item-select-modal";
import { useBoardPermissions } from "~/components/board/permissions/client";
import { useCategoryActions } from "~/components/board/sections/category/category-actions";
@@ -62,8 +64,10 @@ export const BoardContentHeaderActions = () => {
const AddMenu = () => {
const { openModal: openCategoryEditModal } = useModalAction(CategoryEditModal);
const { openModal: openItemSelectModal } = useModalAction(ItemSelectModal);
const { openModal: openAppSelectModal } = useModalAction(AppSelectModal);
const { addCategoryToEnd } = useCategoryActions();
const { addDynamicSection } = useDynamicSectionActions();
const { createItem } = useItemActions();
const t = useI18n();
const handleAddCategory = useCallback(
@@ -90,6 +94,17 @@ const AddMenu = () => {
openItemSelectModal();
}, [openItemSelectModal]);
const handleSelectApp = useCallback(() => {
openAppSelectModal({
onSelect: (appId) => {
createItem({
kind: "app",
options: { appId },
});
},
});
}, [openAppSelectModal, createItem]);
return (
<Menu position="bottom-end" withArrow>
<Menu.Target>
@@ -101,10 +116,14 @@ const AddMenu = () => {
</HeaderButton>
</Menu.Target>
<Menu.Dropdown style={{ transform: "translate(-3px, 0)" }}>
<Menu.Item leftSection={<IconBox size={20} />} onClick={handleSelectItem}>
<Menu.Item leftSection={<IconResize size={20} />} onClick={handleSelectItem}>
{t("item.action.create")}
</Menu.Item>
<Menu.Item leftSection={<IconBox size={20} />} onClick={handleSelectApp}>
{t("app.action.add")}
</Menu.Item>
<Menu.Divider />
<Menu.Item leftSection={<IconBoxAlignTop size={20} />} onClick={handleAddCategory}>
@@ -168,16 +187,18 @@ const SelectBoardsMenu = () => {
</HeaderButton>
</Menu.Target>
<Menu.Dropdown style={{ transform: "translate(-7px, 0)" }}>
{boards.map((board) => (
<Menu.Item
key={board.id}
component={Link}
href={`/boards/${board.name}`}
leftSection={<IconLayoutBoard size={20} />}
>
{board.name}
</Menu.Item>
))}
<ScrollArea.Autosize mah={300}>
{boards.map((board) => (
<Menu.Item
key={board.id}
component={Link}
href={`/boards/${board.name}`}
leftSection={<IconLayoutBoard size={20} />}
>
{board.name}
</Menu.Item>
))}
</ScrollArea.Autosize>
</Menu.Dropdown>
</Menu>
);
@@ -2,7 +2,7 @@
import type { PropsWithChildren } from "react";
import type { MantineColorsTuple } from "@mantine/core";
import { colorsTuple, createTheme, darken, lighten, MantineProvider } from "@mantine/core";
import { colorsTuple, createTheme, darken, lighten, MantineProvider, rem } from "@mantine/core";
import { useRequiredBoard } from "@homarr/boards/context";
import type { ColorScheme } from "@homarr/definitions";
@@ -24,6 +24,11 @@ export const BoardMantineProvider = ({
},
primaryColor: "primaryColor",
autoContrast: true,
fontSizes: {
"2xl": rem(24),
"3xl": rem(28),
"4xl": rem(36),
},
});
return (
@@ -20,7 +20,7 @@ import { useDisclosure } from "@mantine/hooks";
import { useZodForm } from "@homarr/form";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { boardSavePartialSettingsSchema } from "@homarr/validation/board";
import type { Board } from "../../_types";
import { generateColors } from "../../(content)/_theme";
@@ -35,7 +35,7 @@ const hexRegex = /^#[0-9a-fA-F]{6}$/;
const progressPercentageLabel = (value: number) => `${value}%`;
export const ColorSettingsContent = ({ board }: Props) => {
const form = useZodForm(validation.board.savePartialSettings, {
const form = useZodForm(boardSavePartialSettingsSchema, {
initialValues: {
primaryColor: board.primaryColor,
secondaryColor: board.secondaryColor,
@@ -123,7 +123,7 @@ export const ColorSettingsContent = ({ board }: Props) => {
</Grid.Col>
</Grid>
<Group justify="end">
<Button type="submit" loading={isPending} color="teal">
<Button type="submit" loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
@@ -1,14 +1,20 @@
"use client";
import { Button, Grid, Group, Stack, TextInput } from "@mantine/core";
import { startTransition } from "react";
import { ActionIcon, Autocomplete, Button, Center, Grid, Group, Popover, Stack, Text } from "@mantine/core";
import { useDebouncedValue } from "@mantine/hooks";
import { IconPhotoOff, IconUpload } from "@tabler/icons-react";
import { clientApi } from "@homarr/api/client";
import { useSession } from "@homarr/auth/client";
import { backgroundImageAttachments, backgroundImageRepeats, backgroundImageSizes } from "@homarr/definitions";
import { useZodForm } from "@homarr/form";
import { UploadMedia } from "@homarr/forms-collection";
import type { TranslationObject } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client";
import type { SelectItemWithDescriptionBadge } from "@homarr/ui";
import { SelectWithDescriptionBadge } from "@homarr/ui";
import { validation } from "@homarr/validation";
import { boardSavePartialSettingsSchema } from "@homarr/validation/board";
import type { Board } from "../../_types";
import { useSavePartialSettingsMutation } from "./_shared";
@@ -18,8 +24,9 @@ interface Props {
}
export const BackgroundSettingsContent = ({ board }: Props) => {
const t = useI18n();
const { data: session } = useSession();
const { mutate: savePartialSettings, isPending } = useSavePartialSettingsMutation(board);
const form = useZodForm(validation.board.savePartialSettings, {
const form = useZodForm(boardSavePartialSettingsSchema, {
initialValues: {
backgroundImageUrl: board.backgroundImageUrl ?? "",
backgroundImageAttachment: board.backgroundImageAttachment,
@@ -28,6 +35,16 @@ export const BackgroundSettingsContent = ({ board }: Props) => {
},
});
const [debouncedSearch] = useDebouncedValue(form.values.backgroundImageUrl, 200);
const medias = clientApi.media.getPaginated.useQuery({
page: 1,
pageSize: 10,
includeFromAllUsers: true,
search: debouncedSearch ?? "",
});
const images = medias.data?.items.filter((media) => media.contentType.startsWith("image/")) ?? [];
const imageMap = new Map(images.map((image) => [`/api/user-medias/${image.id}`, image]));
const backgroundImageAttachmentData = useBackgroundOptionData(
"backgroundImageAttachment",
backgroundImageAttachments,
@@ -47,10 +64,76 @@ export const BackgroundSettingsContent = ({ board }: Props) => {
<Stack>
<Grid>
<Grid.Col span={12}>
<TextInput
label={t("board.field.backgroundImageUrl.label")}
{...form.getInputProps("backgroundImageUrl")}
/>
<Group wrap="nowrap" gap="xs" w="100%" align="start">
<Autocomplete
flex={1}
leftSection={
form.values.backgroundImageUrl &&
form.values.backgroundImageUrl.trim().length >= 2 && (
<Popover width={300} withArrow>
<Popover.Target>
<Center h="100%">
<ImagePreview src={form.values.backgroundImageUrl} w={20} h={20} />
</Center>
</Popover.Target>
<Popover.Dropdown>
<ImagePreview src={form.values.backgroundImageUrl} w="100%" />
</Popover.Dropdown>
</Popover>
)
}
// We filter it on the server
filter={({ options }) => options}
label={t("board.field.backgroundImageUrl.label")}
placeholder={`${t("board.field.backgroundImageUrl.placeholder")}...`}
renderOption={({ option }) => {
const current = imageMap.get(option.value);
if (!current) return null;
return (
<Group gap="sm">
<ImagePreview src={option.value} w={20} h={20} />
<Stack gap={0}>
<Text size="sm">{current.name}</Text>
<Text size="xs" c="dimmed">
{option.value}
</Text>
</Stack>
</Group>
);
}}
data={[
{
group: t("board.field.backgroundImageUrl.group.your"),
items: images
.filter((media) => media.creatorId === session?.user.id)
.map((media) => `/api/user-medias/${media.id}`),
},
{
group: t("board.field.backgroundImageUrl.group.other"),
items: images
.filter((media) => media.creatorId !== session?.user.id)
.map((media) => `/api/user-medias/${media.id}`),
},
]}
{...form.getInputProps("backgroundImageUrl")}
/>
{session?.user.permissions.includes("media-upload") && (
<UploadMedia
onSuccess={({ url }) =>
startTransition(() => {
form.setFieldValue("backgroundImageUrl", url);
})
}
>
{({ onClick, loading }) => (
<ActionIcon onClick={onClick} loading={loading} mt={24} size={36} variant="default">
<IconUpload size={16} stroke={1.5} />
</ActionIcon>
)}
</UploadMedia>
)}
</Group>
</Grid.Col>
<Grid.Col span={12}>
<SelectWithDescriptionBadge
@@ -76,7 +159,7 @@ export const BackgroundSettingsContent = ({ board }: Props) => {
</Grid>
<Group justify="end">
<Button type="submit" loading={isPending} color="teal">
<Button type="submit" loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
@@ -85,6 +168,21 @@ export const BackgroundSettingsContent = ({ board }: Props) => {
);
};
interface ImagePreviewProps {
src: string;
w: string | number;
h?: string | number;
}
const ImagePreview = ({ src, w, h }: ImagePreviewProps) => {
if (!["/", "http://", "https://"].some((prefix) => src.startsWith(prefix))) {
return <IconPhotoOff size={w} />;
}
// eslint-disable-next-line @next/next/no-img-element
return <img src={src} alt="preview image" style={{ width: w, height: h, objectFit: "contain" }} />;
};
type BackgroundImageKey = "backgroundImageAttachment" | "backgroundImageSize" | "backgroundImageRepeat";
type inferOptions<TKey extends BackgroundImageKey> = TranslationObject["board"]["field"][TKey]["option"];
@@ -38,7 +38,7 @@ export const BehaviorSettingsContent = ({ board }: Props) => {
/>
<Group justify="end">
<Button type="submit" loading={isPending} color="teal">
<Button type="submit" loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
@@ -46,7 +46,7 @@ export const CustomCssSettingsContent = ({ board }: Props) => {
</Alert>
<Group justify="end">
<Button type="submit" loading={isPending} color="teal">
<Button type="submit" loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
@@ -1,14 +1,14 @@
"use client";
import { useEffect, useRef } from "react";
import { Button, Grid, Group, Loader, Stack, TextInput, Tooltip } from "@mantine/core";
import { Button, Grid, Group, Loader, Stack, TextInput } from "@mantine/core";
import { useDebouncedValue, useDocumentTitle, useFavicon } from "@mantine/hooks";
import { IconAlertTriangle } from "@tabler/icons-react";
import { useUpdateBoard } from "@homarr/boards/updater";
import { useZodForm } from "@homarr/form";
import { IconPicker } from "@homarr/forms-collection";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { boardSavePartialSettingsSchema } from "@homarr/validation/board";
import { createMetaTitle } from "~/metadata";
import type { Board } from "../../_types";
@@ -28,7 +28,7 @@ export const GeneralSettingsContent = ({ board }: Props) => {
const { mutate: savePartialSettings, isPending } = useSavePartialSettingsMutation(board);
const form = useZodForm(
validation.board.savePartialSettings
boardSavePartialSettingsSchema
.pick({
pageTitle: true,
logoImageUrl: true,
@@ -52,9 +52,9 @@ export const GeneralSettingsContent = ({ board }: Props) => {
},
);
useLogoPreview(form.values.logoImageUrl);
useFaviconPreview(form.values.faviconImageUrl);
const metaTitleStatus = useMetaTitlePreview(form.values.metaTitle);
const faviconStatus = useFaviconPreview(form.values.faviconImageUrl);
const logoStatus = useLogoPreview(form.values.logoImageUrl);
// Cleanup for not applied changes of the page title and logo image URL
useEffect(() => {
@@ -94,29 +94,29 @@ export const GeneralSettingsContent = ({ board }: Props) => {
<TextInput
label={t("board.field.metaTitle.label")}
placeholder={createMetaTitle(t("board.content.metaTitle", { boardName: board.name }))}
rightSection={<PendingOrInvalidIndicator {...metaTitleStatus} />}
rightSection={metaTitleStatus.isPending && <Loader size="xs" />}
{...form.getInputProps("metaTitle")}
/>
</Grid.Col>
<Grid.Col span={{ xs: 12, md: 6 }}>
<TextInput
<IconPicker
{...form.getInputProps("logoImageUrl")}
label={t("board.field.logoImageUrl.label")}
placeholder="/logo/logo.png"
rightSection={<PendingOrInvalidIndicator {...logoStatus} />}
{...form.getInputProps("logoImageUrl")}
withAsterisk={false}
/>
</Grid.Col>
<Grid.Col span={{ xs: 12, md: 6 }}>
<TextInput
<IconPicker
{...form.getInputProps("faviconImageUrl")}
label={t("board.field.faviconImageUrl.label")}
placeholder="/logo/logo.png"
rightSection={<PendingOrInvalidIndicator {...faviconStatus} />}
{...form.getInputProps("faviconImageUrl")}
withAsterisk={false}
/>
</Grid.Col>
</Grid>
<Group justify="end">
<Button type="submit" loading={isPending} color="teal">
<Button type="submit" loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
@@ -125,40 +125,16 @@ export const GeneralSettingsContent = ({ board }: Props) => {
);
};
const PendingOrInvalidIndicator = ({ isPending, isInvalid }: { isPending: boolean; isInvalid?: boolean }) => {
const t = useI18n();
if (isInvalid) {
return (
<Tooltip multiline w={220} label={t("board.setting.section.general.unrecognizedLink")}>
<IconAlertTriangle size="1rem" color="red" />
</Tooltip>
);
}
if (isPending) {
return <Loader size="xs" />;
}
return null;
};
const useLogoPreview = (url: string | null) => {
const { updateBoard } = useUpdateBoard();
const [logoDebounced] = useDebouncedValue(url ?? "", 500);
useEffect(() => {
if (!logoDebounced.includes(".") && logoDebounced.length >= 1) return;
updateBoard((previous) => ({
...previous,
logoImageUrl: logoDebounced.length >= 1 ? logoDebounced : null,
}));
}, [logoDebounced, updateBoard]);
return {
isPending: (url ?? "") !== logoDebounced,
isInvalid: logoDebounced.length >= 1 && !logoDebounced.includes("."),
};
};
const useMetaTitlePreview = (title: string | null) => {
@@ -170,16 +146,7 @@ const useMetaTitlePreview = (title: string | null) => {
};
};
const validFaviconExtensions = ["ico", "png", "svg", "gif"];
const isValidUrl = (url: string) =>
url.includes("/") && validFaviconExtensions.some((extension) => url.endsWith(`.${extension}`));
const useFaviconPreview = (url: string | null) => {
const [faviconDebounced] = useDebouncedValue(url ?? "", 500);
useFavicon(isValidUrl(faviconDebounced) ? faviconDebounced : "");
return {
isPending: (url ?? "") !== faviconDebounced,
isInvalid: faviconDebounced.length >= 1 && !isValidUrl(faviconDebounced),
};
useFavicon(faviconDebounced);
};
@@ -1,45 +1,111 @@
"use client";
import { Button, Grid, Group, Input, Slider, Stack } from "@mantine/core";
import { Button, Fieldset, Grid, Group, Input, NumberInput, Slider, Stack, Text, TextInput } from "@mantine/core";
import { clientApi } from "@homarr/api/client";
import { createId } from "@homarr/db/client";
import { useZodForm } from "@homarr/form";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { boardSaveLayoutsSchema } from "@homarr/validation/board";
import type { Board } from "../../_types";
import { useSavePartialSettingsMutation } from "./_shared";
interface Props {
board: Board;
}
export const LayoutSettingsContent = ({ board }: Props) => {
const t = useI18n();
const { mutate: savePartialSettings, isPending } = useSavePartialSettingsMutation(board);
const form = useZodForm(validation.board.savePartialSettings.pick({ columnCount: true }).required(), {
const utils = clientApi.useUtils();
const { mutate: saveLayouts, isPending } = clientApi.board.saveLayouts.useMutation({
onSettled() {
void utils.board.getBoardByName.invalidate({ name: board.name });
void utils.board.getHomeBoard.invalidate();
},
});
const form = useZodForm(boardSaveLayoutsSchema.omit({ id: true }).required(), {
initialValues: {
columnCount: board.columnCount,
layouts: board.layouts,
},
});
return (
<form
onSubmit={form.onSubmit((values) => {
savePartialSettings({
saveLayouts({
id: board.id,
...values,
});
})}
>
<Stack>
<Grid>
<Grid.Col span={{ sm: 12, md: 6 }}>
<Input.Wrapper label={t("board.field.columnCount.label")}>
<Slider mt="xs" min={1} max={24} step={1} {...form.getInputProps("columnCount")} />
</Input.Wrapper>
</Grid.Col>
</Grid>
<Stack gap="sm">
<Group justify="space-between" align="center">
<Text fw={500}>{t("board.setting.section.layout.responsive.title")}</Text>
<Button
variant="subtle"
onClick={() => {
form.setValues({
layouts: [
...form.values.layouts,
{
id: createId(),
name: "",
columnCount: 10,
breakpoint: 0,
},
],
});
}}
>
{t("board.setting.section.layout.responsive.action.add")}
</Button>
</Group>
{form.values.layouts.map((layout, index) => (
<Fieldset key={layout.id} legend={layout.name} bg="transparent">
<Grid>
<Grid.Col span={{ sm: 12, md: 6 }}>
<TextInput {...form.getInputProps(`layouts.${index}.name`)} label={t("layout.field.name.label")} />
</Grid.Col>
<Grid.Col span={{ sm: 12, md: 6 }}>
<Input.Wrapper label={t("layout.field.columnCount.label")}>
<Slider mt="xs" min={1} max={24} step={1} {...form.getInputProps(`layouts.${index}.columnCount`)} />
</Input.Wrapper>
</Grid.Col>
<Grid.Col span={{ sm: 12, md: 6 }}>
<NumberInput
{...form.getInputProps(`layouts.${index}.breakpoint`)}
label={t("layout.field.breakpoint.label")}
description={t("layout.field.breakpoint.description")}
/>
</Grid.Col>
</Grid>
{form.values.layouts.length >= 2 && (
<Group justify="end">
<Button
variant="subtle"
onClick={() => {
form.setValues((previous) =>
previous.layouts !== undefined && previous.layouts.length >= 2
? {
layouts: form.values.layouts.filter((filteredLayout) => filteredLayout.id !== layout.id),
}
: previous,
);
}}
>
{t("common.action.remove")}
</Button>
</Group>
)}
</Fieldset>
))}
</Stack>
<Group justify="end">
<Button type="submit" loading={isPending} color="teal">
<Button type="submit" loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
@@ -3,10 +3,14 @@ import type { WidgetKind } from "@homarr/definitions";
export type Board = RouterOutputs["board"]["getHomeBoard"];
export type Section = Board["sections"][number];
export type Item = Section["items"][number];
export type Item = Board["items"][number];
export type ItemLayout = Item["layouts"][number];
export type SectionItem = Omit<Item, "layouts"> & ItemLayout & { type: "item" };
export type CategorySection = Extract<Section, { kind: "category" }>;
export type EmptySection = Extract<Section, { kind: "empty" }>;
export type DynamicSection = Extract<Section, { kind: "dynamic" }>;
export type DynamicSectionLayout = DynamicSection["layouts"][number];
export type DynamicSectionItem = Omit<DynamicSection, "layouts"> & DynamicSectionLayout & { type: "section" };
export type ItemOfKind<TKind extends WidgetKind> = Extract<Item, { kind: TKind }>;
@@ -8,18 +8,18 @@ import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { groupCreateSchema } from "@homarr/validation/group";
export const InitGroup = () => {
const t = useI18n();
const { mutateAsync } = clientApi.group.createInitialExternalGroup.useMutation();
const form = useZodForm(validation.group.create, {
const form = useZodForm(groupCreateSchema, {
initialValues: {
name: "",
},
});
const handleSubmitAsync = async (values: z.infer<typeof validation.group.create>) => {
const handleSubmitAsync = async (values: z.infer<typeof groupCreateSchema>) => {
await mutateAsync(values, {
async onSuccess() {
await revalidatePathActionAsync("/init");
@@ -12,13 +12,13 @@ import type { CheckboxProps } from "@homarr/form/types";
import { defaultServerSettings } from "@homarr/server-settings";
import type { TranslationObject } from "@homarr/translation";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { settingsInitSchema } from "@homarr/validation/settings";
export const InitSettings = () => {
const tSection = useScopedI18n("management.page.settings.section");
const t = useI18n();
const { mutateAsync } = clientApi.serverSettings.initSettings.useMutation();
const form = useZodForm(validation.settings.init, { initialValues: defaultServerSettings });
const form = useZodForm(settingsInitSchema, { initialValues: defaultServerSettings });
form.watch("analytics.enableGeneral", ({ value }) => {
if (!value) {
@@ -30,7 +30,7 @@ export const InitSettings = () => {
}
});
const handleSubmitAsync = async (values: z.infer<typeof validation.settings.init>) => {
const handleSubmitAsync = async (values: z.infer<typeof settingsInitSchema>) => {
await mutateAsync(values, {
async onSuccess() {
await revalidatePathActionAsync("/init");
@@ -4,18 +4,19 @@ import { Button, PasswordInput, Stack, TextInput } from "@mantine/core";
import type { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { signIn } from "@homarr/auth/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client";
import { CustomPasswordInput } from "@homarr/ui";
import { validation } from "@homarr/validation";
import { userInitSchema } from "@homarr/validation/user";
export const InitUserForm = () => {
const t = useScopedI18n("user");
const tUser = useScopedI18n("init.step.user");
const { mutateAsync, isPending } = clientApi.user.initUser.useMutation();
const form = useZodForm(validation.user.init, {
const form = useZodForm(userInitSchema, {
initialValues: {
username: "",
password: "",
@@ -30,6 +31,13 @@ export const InitUserForm = () => {
title: tUser("notification.success.title"),
message: tUser("notification.success.message"),
});
await signIn("credentials", {
name: values.username,
password: values.password,
redirect: false,
});
await revalidatePathActionAsync("/init");
},
onError: (error) => {
@@ -66,4 +74,4 @@ export const InitUserForm = () => {
);
};
type FormType = z.infer<typeof validation.user.init>;
type FormType = z.infer<typeof userInitSchema>;
+11 -4
View File
@@ -7,6 +7,7 @@ import "@homarr/ui/styles.css";
import "~/styles/scroll-area.scss";
import { notFound } from "next/navigation";
import type { DayOfWeek } from "@mantine/dates";
import { NextIntlClientProvider } from "next-intl";
import { api } from "@homarr/api/server";
@@ -20,7 +21,6 @@ import { SettingsProvider } from "@homarr/settings";
import { SpotlightProvider } from "@homarr/spotlight";
import type { SupportedLanguage } from "@homarr/translation";
import { isLocaleRTL, isLocaleSupported } from "@homarr/translation";
import { getI18nMessages } from "@homarr/translation/server";
import { Analytics } from "~/components/layout/analytics";
import { SearchEngineOptimization } from "~/components/layout/search-engine-optimization";
@@ -81,7 +81,6 @@ export default async function Layout(props: {
const serverSettings = await getServerSettingsAsync(db);
const colorScheme = await getCurrentColorSchemeAsync();
const direction = isLocaleRTL((await props.params).locale) ? "rtl" : "ltr";
const i18nMessages = await getI18nMessages();
const StackedProvider = composeWrappers([
(innerProps) => {
@@ -89,7 +88,15 @@ export default async function Layout(props: {
},
(innerProps) => (
<SettingsProvider
user={user}
user={
user
? {
...user,
// Convert type, because output schema is not smart enough to infer $type from drizzle
firstDayOfWeek: user.firstDayOfWeek as DayOfWeek,
}
: null
}
serverSettings={{
board: {
homeBoardId: serverSettings.board.homeBoardId,
@@ -105,7 +112,7 @@ export default async function Layout(props: {
(innerProps) => <JotaiProvider {...innerProps} />,
(innerProps) => <TRPCReactProvider {...innerProps} />,
(innerProps) => <DayJsLoader {...innerProps} />,
(innerProps) => <NextIntlClientProvider {...innerProps} messages={i18nMessages} />,
(innerProps) => <NextIntlClientProvider {...innerProps} />,
(innerProps) => <CustomMantineProvider {...innerProps} defaultColorScheme={colorScheme} />,
(innerProps) => <ModalProvider {...innerProps} />,
(innerProps) => <SpotlightProvider {...innerProps} />,
@@ -80,7 +80,7 @@ export default async function AboutPage() {
<Text>{t("accordion.contributors.title")}</Text>
<Text size="sm" c="dimmed">
{t("accordion.contributors.subtitle", {
count: githubContributors.length,
count: String(githubContributors.length),
})}
</Text>
</Stack>
@@ -104,7 +104,7 @@ export default async function AboutPage() {
<Text>{t("accordion.translators.title")}</Text>
<Text size="sm" c="dimmed">
{t("accordion.translators.subtitle", {
count: crowdinContributors.length,
count: String(crowdinContributors.length),
})}
</Text>
</Stack>
@@ -128,7 +128,7 @@ export default async function AboutPage() {
<Text>{t("accordion.libraries.title")}</Text>
<Text size="sm" c="dimmed">
{t("accordion.libraries.subtitle", {
count: Object.keys(attributes.dependencies).length,
count: String(Object.keys(attributes.dependencies).length),
})}
</Text>
</Stack>
@@ -23,7 +23,9 @@ export const AppDeleteButton = ({ app }: AppDeleteButtonProps) => {
const onClick = useCallback(() => {
openConfirmModal({
title: t("title"),
children: t("message", app),
children: t("message", {
name: app.name,
}),
onConfirm: () => {
mutate(
{ id: app.id },
@@ -10,7 +10,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { AppForm } from "@homarr/forms-collection";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import type { validation } from "@homarr/validation";
import type { appManageSchema } from "@homarr/validation/app";
interface AppEditFormProps {
app: RouterOutputs["app"]["byId"];
@@ -40,7 +40,7 @@ export const AppEditForm = ({ app }: AppEditFormProps) => {
});
const handleSubmit = useCallback(
(values: z.infer<typeof validation.app.manage>) => {
(values: z.infer<typeof appManageSchema>) => {
mutate({
id: app.id,
...values,
@@ -61,7 +61,8 @@ export default async function AppsPage(props: AppsPageProps) {
</Stack>
)}
<Group justify="end">
{/* Added margin to not hide pagination behind affix-button */}
<Group justify="end" mb={48}>
<TablePagination total={Math.ceil(totalCount / searchParams.pageSize)} />
</Group>
</Stack>
@@ -14,7 +14,7 @@ import { convertIntegrationTestConnectionError } from "@homarr/integrations/clie
import { useConfirmModal } from "@homarr/modals";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { integrationUpdateSchema } from "@homarr/validation/integration";
import { SecretCard } from "../../_components/secrets/integration-secret-card";
import { IntegrationSecretInput } from "../../_components/secrets/integration-secret-inputs";
@@ -32,7 +32,7 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
) ?? getDefaultSecretKinds(integration.kind);
const router = useRouter();
const form = useZodForm(validation.integration.update.omit({ id: true }), {
const form = useZodForm(integrationUpdateSchema.omit({ id: true }), {
initialValues: {
name: integration.name,
url: integration.url,
@@ -141,4 +141,4 @@ export const EditIntegrationForm = ({ integration }: EditIntegrationForm) => {
);
};
type FormType = Omit<z.infer<typeof validation.integration.update>, "id">;
type FormType = Omit<z.infer<typeof integrationUpdateSchema>, "id">;
@@ -1,36 +1,56 @@
"use client";
import { useCallback } from "react";
import { useCallback, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Alert, Button, Checkbox, Fieldset, Group, SegmentedControl, Stack, Text, TextInput } from "@mantine/core";
import {
Alert,
Button,
Checkbox,
Collapse,
Fieldset,
Group,
SegmentedControl,
Stack,
Text,
TextInput,
} from "@mantine/core";
import { IconInfoCircle } from "@tabler/icons-react";
import type { z } from "zod";
import { z } from "zod";
import { clientApi } from "@homarr/api/client";
import { revalidatePathActionAsync } from "@homarr/common/client";
import type { IntegrationKind, IntegrationSecretKind } from "@homarr/definitions";
import { getAllSecretKindOptions, getIntegrationName, integrationDefs } from "@homarr/definitions";
import { getAllSecretKindOptions, getIconUrl, getIntegrationName, integrationDefs } from "@homarr/definitions";
import type { UseFormReturnType } from "@homarr/form";
import { useZodForm } from "@homarr/form";
import { convertIntegrationTestConnectionError } from "@homarr/integrations/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { appHrefSchema } from "@homarr/validation/app";
import { integrationCreateSchema } from "@homarr/validation/integration";
import { IntegrationSecretInput } from "../_components/secrets/integration-secret-inputs";
interface NewIntegrationFormProps {
searchParams: Partial<z.infer<typeof validation.integration.create>> & {
searchParams: Partial<z.infer<typeof integrationCreateSchema>> & {
kind: IntegrationKind;
};
}
const formSchema = integrationCreateSchema.omit({ kind: true }).and(
z.object({
createApp: z.boolean(),
appHref: appHrefSchema,
}),
);
export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) => {
const t = useI18n();
const secretKinds = getAllSecretKindOptions(searchParams.kind);
const router = useRouter();
const form = useZodForm(validation.integration.create.omit({ kind: true }), {
const [opened, setOpened] = useState(false);
const form = useZodForm(formSchema, {
initialValues: {
name: searchParams.name ?? getIntegrationName(searchParams.kind),
url: searchParams.url ?? "",
@@ -39,23 +59,60 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) =>
value: "",
})),
attemptSearchEngineCreation: true,
createApp: false,
appHref: "",
},
onValuesChange(values, previous) {
if (values.createApp !== previous.createApp) {
setOpened(values.createApp);
}
},
});
const { mutateAsync, isPending } = clientApi.integration.create.useMutation();
const { mutateAsync: createIntegrationAsync, isPending: isPendingIntegration } =
clientApi.integration.create.useMutation();
const { mutateAsync: createAppAsync, isPending: isPendingApp } = clientApi.app.create.useMutation();
const isPending = isPendingIntegration || isPendingApp;
const handleSubmitAsync = async (values: FormType) => {
await mutateAsync(
await createIntegrationAsync(
{
kind: searchParams.kind,
...values,
},
{
onSuccess: () => {
async onSuccess() {
showSuccessNotification({
title: t("integration.page.create.notification.success.title"),
message: t("integration.page.create.notification.success.message"),
});
void revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
if (!values.createApp) {
await revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
return;
}
const hasCustomHref = values.appHref !== null && values.appHref.trim().length >= 1;
await createAppAsync(
{
name: values.name,
href: hasCustomHref ? values.appHref : values.url,
iconUrl: getIconUrl(searchParams.kind),
description: null,
pingUrl: values.url,
},
{
async onSettled() {
await revalidatePathActionAsync("/manage/integrations").then(() => router.push("/manage/integrations"));
},
onError() {
showErrorNotification({
title: t("app.page.create.notification.error.title"),
message: t("app.page.create.notification.error.message"),
});
},
},
);
},
onError: (error) => {
const testConnectionError = convertIntegrationTestConnectionError(error.data?.error);
@@ -117,6 +174,16 @@ export const NewIntegrationForm = ({ searchParams }: NewIntegrationFormProps) =>
/>
)}
<Checkbox
{...form.getInputProps("createApp", { type: "checkbox" })}
label={t("integration.field.createApp.label")}
description={t("integration.field.createApp.description")}
/>
<Collapse in={opened}>
<TextInput placeholder={t("integration.field.appHref.placeholder")} {...form.getInputProps("appHref")} />
</Collapse>
<Group justify="end" align="center">
<Button variant="default" component={Link} href="/manage/integrations">
{t("common.action.backToOverview")}
@@ -166,4 +233,4 @@ const SecretKindsSegmentedControl = ({ secretKinds, form }: SecretKindsSegmented
return <SegmentedControl fullWidth data={secretKindGroups} onChange={onChange}></SegmentedControl>;
};
type FormType = Omit<z.infer<typeof validation.integration.create>, "kind">;
type FormType = z.infer<typeof formSchema>;
@@ -7,14 +7,14 @@ import type { IntegrationKind } from "@homarr/definitions";
import { getIntegrationName, integrationKinds } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server";
import { IntegrationAvatar } from "@homarr/ui";
import type { validation } from "@homarr/validation";
import type { integrationCreateSchema } from "@homarr/validation/integration";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { NewIntegrationForm } from "./_integration-new-form";
interface NewIntegrationPageProps {
searchParams: Promise<
Partial<z.infer<typeof validation.integration.create>> & {
Partial<z.infer<typeof integrationCreateSchema>> & {
kind: IntegrationKind;
}
>;
@@ -208,21 +208,20 @@ const IntegrationList = async ({ integrations, activeTab }: IntegrationListProps
<Stack gap={0}>
<Group justify="space-between" align="center" wrap="nowrap">
<Text>{integration.name}</Text>
{hasFullAccess ||
(integration.permissions.hasFullAccess && (
<ActionIconGroup>
<ActionIcon
component={Link}
href={`/manage/integrations/edit/${integration.id}`}
variant="subtle"
color="gray"
aria-label={t("page.edit.title", { name: getIntegrationName(integration.kind) })}
>
<IconPencil size={16} stroke={1.5} />
</ActionIcon>
<DeleteIntegrationActionButton integration={integration} count={integrations.length} />
</ActionIconGroup>
))}
{(hasFullAccess || integration.permissions.hasFullAccess) && (
<ActionIconGroup>
<ActionIcon
component={Link}
href={`/manage/integrations/edit/${integration.id}`}
variant="subtle"
color="gray"
aria-label={t("page.edit.title", { name: getIntegrationName(integration.kind) })}
>
<IconPencil size={16} stroke={1.5} />
</ActionIcon>
<DeleteIntegrationActionButton integration={integration} count={integrations.length} />
</ActionIconGroup>
)}
</Group>
<Anchor href={integration.url} target="_blank" rel="noreferrer" size="sm">
{integration.url}
@@ -28,6 +28,7 @@ import {
import { auth } from "@homarr/auth/next";
import { isProviderEnabled } from "@homarr/auth/server";
import { createDocumentationLink } from "@homarr/definitions";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { MainHeader } from "~/components/layout/header";
@@ -113,7 +114,13 @@ export default async function ManageLayout({ children }: PropsWithChildren) {
label: t("items.tools.items.docker"),
icon: IconBrandDocker,
href: "/manage/tools/docker",
hidden: !session?.user.permissions.includes("admin"),
hidden: !(session?.user.permissions.includes("admin") && env.ENABLE_DOCKER),
},
{
label: t("items.tools.items.kubernetes"),
icon: IconBox,
href: "/manage/tools/kubernetes",
hidden: !(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES),
},
{
label: t("items.tools.items.api"),
@@ -92,7 +92,8 @@ export default async function GroupsListPage(props: MediaListPageProps) {
</TableTbody>
</Table>
<Group justify="end">
{/* Added margin to not hide pagination behind affix-button */}
<Group justify="end" mb={48}>
<TablePagination total={Math.ceil(totalCount / searchParams.pageSize)} />
</Group>
</Stack>
@@ -12,9 +12,9 @@ import { useZodForm } from "@homarr/form";
import { IconPicker } from "@homarr/forms-collection";
import type { TranslationFunction } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { searchEngineManageSchema } from "@homarr/validation/search-engine";
type FormType = z.infer<typeof validation.searchEngine.manage>;
type FormType = z.infer<typeof searchEngineManageSchema>;
interface SearchEngineFormProps {
submitButtonTranslation: (t: TranslationFunction) => string;
@@ -30,7 +30,7 @@ export const SearchEngineForm = (props: SearchEngineFormProps) => {
const [integrationData] = clientApi.integration.allThatSupportSearch.useSuspenseQuery();
const form = useZodForm(validation.searchEngine.manage, {
const form = useZodForm(searchEngineManageSchema, {
initialValues: initialValues ?? {
name: "",
short: "",
@@ -23,7 +23,9 @@ export const SearchEngineDeleteButton = ({ searchEngine }: SearchEngineDeleteBut
const onClick = useCallback(() => {
openConfirmModal({
title: t("title"),
children: t("message", searchEngine),
children: t("message", {
name: searchEngine.name,
}),
onConfirm: () => {
mutate(
{ id: searchEngine.id },
@@ -10,7 +10,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import type { TranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import type { validation } from "@homarr/validation";
import type { searchEngineManageSchema } from "@homarr/validation/search-engine";
import { SearchEngineForm } from "../../_form";
@@ -41,7 +41,7 @@ export const SearchEngineEditForm = ({ searchEngine }: SearchEngineEditFormProps
});
const handleSubmit = useCallback(
(values: z.infer<typeof validation.searchEngine.manage>) => {
(values: z.infer<typeof searchEngineManageSchema>) => {
mutate({
id: searchEngine.id,
...values,
@@ -9,7 +9,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import type { TranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import type { validation } from "@homarr/validation";
import type { searchEngineManageSchema } from "@homarr/validation/search-engine";
import { SearchEngineForm } from "../_form";
@@ -35,7 +35,7 @@ export const SearchEngineNewForm = () => {
});
const handleSubmit = useCallback(
(values: z.infer<typeof validation.searchEngine.manage>) => {
(values: z.infer<typeof searchEngineManageSchema>) => {
mutate(values);
},
[mutate],
@@ -61,7 +61,8 @@ export default async function SearchEnginesPage(props: SearchEnginesPageProps) {
</Stack>
)}
<Group justify="end">
{/* Added margin to not hide pagination behind affix-button */}
<Group justify="end" mb={48}>
<TablePagination total={Math.ceil(totalCount / searchParams.pageSize)} />
</Group>
</Stack>
@@ -10,7 +10,7 @@ import { useZodForm } from "@homarr/form";
import { createModal, useModalAction } from "@homarr/modals";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { superRefineCertificateFile } from "@homarr/validation";
import { superRefineCertificateFile } from "@homarr/validation/certificates";
export const AddCertificateButton = () => {
const { openModal } = useModalAction(AddCertificateModal);
@@ -1,7 +1,7 @@
import { X509Certificate } from "node:crypto";
import { notFound } from "next/navigation";
import { Card, Group, SimpleGrid, Stack, Text, Title } from "@mantine/core";
import { IconCertificate, IconCertificateOff } from "@tabler/icons-react";
import { IconAlertTriangle, IconCertificate, IconCertificateOff } from "@tabler/icons-react";
import dayjs from "dayjs";
import { auth } from "@homarr/auth/next";
@@ -31,11 +31,27 @@ export default async function CertificatesPage({ params }: CertificatesPageProps
const t = await getI18n();
const certificates = await loadCustomRootCertificatesAsync();
const x509Certificates = certificates
.map((cert) => ({
...cert,
x509: new X509Certificate(cert.content),
}))
.sort((certA, certB) => certA.x509.validToDate.getTime() - certB.x509.validToDate.getTime());
.map((cert) => {
try {
const x509 = new X509Certificate(cert.content);
return {
...cert,
isError: false,
x509,
} as const;
} catch {
return {
...cert,
isError: true,
x509: null,
} as const;
}
})
.sort((certA, certB) => {
if (certA.isError) return -1;
if (certB.isError) return 1;
return certA.x509.validToDate.getTime() - certB.x509.validToDate.getTime();
});
return (
<>
@@ -57,32 +73,47 @@ export default async function CertificatesPage({ params }: CertificatesPageProps
<SimpleGrid cols={{ sm: 1, lg: 2, xl: 3 }} spacing="lg">
{x509Certificates.map((cert) => (
<Card key={cert.x509.fingerprint} withBorder>
<Card key={cert.fileName} withBorder>
<Group wrap="nowrap">
<IconCertificate
color={getMantineColor(iconColor(cert.x509.validToDate), 6)}
style={{ minWidth: 32 }}
size={32}
stroke={1.5}
/>
{cert.isError ? (
<IconAlertTriangle
color={getMantineColor("red", 6)}
style={{ minWidth: 32 }}
size={32}
stroke={1.5}
/>
) : (
<IconCertificate
color={getMantineColor(iconColor(cert.x509.validToDate), 6)}
style={{ minWidth: 32 }}
size={32}
stroke={1.5}
/>
)}
<Stack flex={1} gap="xs" maw="calc(100% - 48px)">
<Group justify="space-between" wrap="nowrap">
<Text fw={500} lineClamp={1} style={{ wordBreak: "break-all" }}>
{cert.x509.subject}
{cert.isError ? t("certificate.page.list.invalid.title") : cert.x509.subject}
</Text>
<Text c="gray.6" ta="end" size="sm">
{cert.fileName}
</Text>
</Group>
<Group justify="space-between">
<Text size="sm" c="gray.6" title={cert.x509.validToDate.toISOString()}>
{t("certificate.page.list.expires", {
when: new Intl.RelativeTimeFormat(locale).format(
dayjs(cert.x509.validToDate).diff(dayjs(), "days"),
"days",
),
})}
</Text>
{cert.isError ? (
<Text size="sm" c="gray.6">
{t("certificate.page.list.invalid.description")}
</Text>
) : (
<Text size="sm" c="gray.6" title={cert.x509.validToDate.toISOString()}>
{t("certificate.page.list.expires", {
when: new Intl.RelativeTimeFormat(locale).format(
dayjs(cert.x509.validToDate).diff(dayjs(), "days"),
"days",
),
})}
</Text>
)}
<RemoveCertificate fileName={cert.fileName} />
</Group>
</Stack>
@@ -35,7 +35,13 @@ const createColumns = (
Cell({ renderedCellValue, row }) {
return (
<Group gap="xs">
<Avatar variant="outline" radius="lg" size="md" src={row.original.iconUrl}>
<Avatar
variant="outline"
radius="lg"
size="md"
styles={{ image: { objectFit: "contain" } }}
src={row.original.iconUrl}
>
{row.original.name.at(0)?.toUpperCase()}
</Avatar>
<Text>{renderedCellValue}</Text>
@@ -98,7 +104,7 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers"
enableBottomToolbar: false,
positionGlobalFilter: "right",
mantineSearchTextInputProps: {
placeholder: tDocker("table.search", { count: data.containers.length }),
placeholder: tDocker("table.search", { count: String(data.containers.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
@@ -140,8 +146,8 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers"
{groupedAlert}
<Text fw={500}>
{tDocker("table.selected", {
selectCount: table.getSelectedRowModel().rows.length,
totalCount: table.getRowCount(),
selectCount: String(table.getSelectedRowModel().rows.length),
totalCount: String(table.getRowCount()),
})}
</Text>
<ContainerActionBar selectedContainers={dockerContainers} />
@@ -3,6 +3,7 @@ import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
@@ -10,7 +11,7 @@ import { DockerTable } from "./docker-table";
export default async function DockerPage() {
const session = await auth();
if (!session?.user || !session.user.permissions.includes("admin")) {
if (!(session?.user.permissions.includes("admin") && env.ENABLE_DOCKER)) {
notFound();
}
@@ -0,0 +1,76 @@
"use client";
import { SimpleGrid, Skeleton, Stack, Title } from "@mantine/core";
import { clientApi } from "@homarr/api/client";
import { createId } from "@homarr/db/client";
import type { KubernetesLabelResourceType } from "@homarr/definitions";
import { useI18n } from "@homarr/translation/client";
import KubernetesErrorPage from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/error";
import { HeaderCard } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card";
import { ResourceGauge } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-gauge";
import { ResourceTile } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile";
export function ClusterDashboard() {
const t = useI18n();
const {
data: clusterData,
isLoading: isClusterLoading,
isError: isClusterError,
} = clientApi.kubernetes.cluster.getCluster.useQuery();
const {
data: resourceCountsData,
isLoading: isResourceCountsLoading,
isError: isResourceCountsError,
} = clientApi.kubernetes.cluster.getClusterResourceCounts.useQuery();
return (
<Stack bg="var(--mantine-color-body)">
<Title>{t("kubernetes.cluster.title")}</Title>
<SimpleGrid cols={{ xs: 1, sm: 2, md: 3 }}>
{isClusterError ? (
Array.from({ length: 3 }).map(() => <KubernetesErrorPage key={createId()} />)
) : isClusterLoading ? (
Array.from({ length: 3 }).map(() => <Skeleton key={createId()} height={65} />)
) : (
<>
<HeaderCard headerType={"providers"} value={clusterData ? clusterData.providers : ""} />
<HeaderCard headerType={"version"} value={clusterData ? clusterData.kubernetesVersion : ""} />
<HeaderCard headerType={"architecture"} value={clusterData ? clusterData.architecture : ""} />
</>
)}
</SimpleGrid>
<Title>{t("kubernetes.cluster.capacity.title")}</Title>
<SimpleGrid cols={{ xs: 1, sm: 2, md: 3 }}>
{isClusterError
? Array.from({ length: 3 }).map(() => <KubernetesErrorPage key={createId()} />)
: isClusterLoading
? Array.from({ length: 3 }).map(() => <Skeleton key={createId()} height={200} />)
: clusterData?.capacity.map((capacity) => (
<ResourceGauge kubernetesCapacity={capacity} key={capacity.type} />
))}
</SimpleGrid>
<Title>{t("kubernetes.cluster.resources.title")}</Title>
<SimpleGrid cols={{ xs: 1, sm: 2, md: 3 }}>
{isResourceCountsError
? Array.from({ length: 8 }).map(() => <KubernetesErrorPage key={createId()} />)
: isResourceCountsLoading
? Array.from({ length: 8 }).map(() => <Skeleton key={createId()} height={100} />)
: resourceCountsData?.map((clusterResourceCount) => (
<ResourceTile
count={clusterResourceCount.count}
label={clusterResourceCount.label as KubernetesLabelResourceType}
key={clusterResourceCount.label}
/>
))}
</SimpleGrid>
</Stack>
);
}
@@ -0,0 +1,27 @@
"use client";
import Link from "next/link";
import { Anchor, Center, Stack, Text } from "@mantine/core";
import { IconCubeOff } from "@tabler/icons-react";
import { useI18n } from "@homarr/translation/client";
export default function KubernetesErrorPage() {
const t = useI18n();
return (
<Center>
<Stack align="center">
<IconCubeOff size={48} stroke={1.5} />
<Stack align="center" gap="xs">
<Text size="lg" fw={500}>
{t("kubernetes.error.internalServerError")}
</Text>
<Anchor size="sm" component={Link} href="/manage/tools/logs">
{t("common.action.checkLogs")}
</Anchor>
</Stack>
</Stack>
</Center>
);
}
@@ -0,0 +1,31 @@
.header {
direction: inherit;
position: relative;
overflow: hidden;
padding: var(--mantine-spacing-xs);
padding-left: calc(var(--mantine-spacing-xs) * 2);
@mixin hover {
box-shadow: var(--mantine-shadow-md);
}
&::before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 6px;
background-image: linear-gradient(0, var(--mantine-color-blue-4), var(--mantine-color-blue-9));
}
@mixin rtl {
padding-left: var(--mantine-spacing-xs);
padding-right: calc(var(--mantine-spacing-xs) * 2);
&::before {
left: unset;
right: 0;
}
}
}
@@ -0,0 +1,44 @@
import { Card, Flex, Text, ThemeIcon } from "@mantine/core";
import { isLocaleRTL } from "@homarr/translation";
import { useCurrentLocale, useI18n } from "@homarr/translation/client";
import { HeaderIcon } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-icon";
import classes from "./header-card.module.css";
export type HeaderTypes = "providers" | "version" | "architecture";
interface HeaderCardProps {
headerType: HeaderTypes;
value: string;
}
export function HeaderCard(props: HeaderCardProps) {
const t = useI18n();
const currentLocale = useCurrentLocale();
const isRTL = isLocaleRTL(currentLocale);
return (
<Card className={classes.header}>
<Flex align="center" justify={isRTL ? "space-between" : "flex-start"} gap="md" direction={"row"}>
<ThemeIcon
size="xl"
radius="md"
variant="gradient"
gradient={{
deg: 0,
from: "var(--mantine-color-blue-4)",
to: "var(--mantine-color-blue-9)",
}}
>
<HeaderIcon type={props.headerType} />
</ThemeIcon>
<Text size="xl" fw={500} dir={isRTL ? "rtl" : "ltr"}>
{isRTL
? `${props.value} : ${t(`kubernetes.cluster.${props.headerType}`)}`
: `${t(`kubernetes.cluster.${props.headerType}`)} : ${props.value}`}
</Text>
</Flex>
</Card>
);
}
@@ -0,0 +1,18 @@
import { IconBrandGit, IconCloudShare, IconGeometry } from "@tabler/icons-react";
import type { HeaderTypes } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card";
interface HeaderIconProps {
type: HeaderTypes;
}
export function HeaderIcon({ type }: HeaderIconProps) {
switch (type) {
case "providers":
return <IconCloudShare size={28} stroke={1.5} />;
case "version":
return <IconBrandGit size={28} stroke={1.5} />;
default:
return <IconGeometry size={28} stroke={1.5} />;
}
}
@@ -0,0 +1,20 @@
.paper {
position: relative;
overflow: visible;
padding: var(--mantine-spacing-xl);
padding-top: calc(var(--mantine-spacing-xl) * 1.5 + 20px);
}
.icon {
position: absolute;
top: -20px;
left: calc(50% - 30px);
border: groove white;
}
.title {
font-family:
Greycliff CF,
var(--mantine-font-family);
line-height: 1;
}
@@ -0,0 +1,90 @@
import React from "react";
import { Group, Paper, Progress, Text, ThemeIcon } from "@mantine/core";
import type { KubernetesCapacity } from "@homarr/definitions";
import { isLocaleRTL } from "@homarr/translation";
import { useCurrentLocale, useI18n } from "@homarr/translation/client";
import { ResourceIcon } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-gauge/resource-icon";
import classes from "./resource-gauge.module.css";
interface KubernetesResourceGaugeProps {
kubernetesCapacity: KubernetesCapacity;
}
export function ResourceGauge(props: KubernetesResourceGaugeProps) {
const t = useI18n();
const currentLocale = useCurrentLocale();
const isRTL = Boolean(isLocaleRTL(currentLocale));
return (
<Paper radius="md" withBorder className={classes.paper} mt={20}>
<ThemeIcon className={classes.icon} size={60} radius={60} bg={"#326ce5"}>
<ResourceIcon type={props.kubernetesCapacity.type} />
</ThemeIcon>
<Text ta="center" fw={700} className={classes.title}>
{props.kubernetesCapacity.type}
</Text>
{props.kubernetesCapacity.resourcesStats.map((stat) => {
const isReserved = stat.type === "Reserved";
const labelKey = isReserved
? "kubernetes.cluster.capacity.resource.reserved"
: "kubernetes.cluster.capacity.resource.used";
return (
<div key={stat.percentageValue}>
<Group justify={"space-between"} mt="xs">
<Text fz="sm" c="dimmed">
{isRTL ? (
<>
{stat.capacityUnit && (
<Text component="span" mr={4}>
{stat.capacityUnit}
</Text>
)}
<Text component="span">
{stat.maxUsedValue} / {stat.usedValue}{" "}
</Text>
<Text component="span" fw={500}>
{t(labelKey)}
</Text>
</>
) : (
<>
<Text component="span" fw={500}>
{t(labelKey)}
</Text>
<Text component="span">
{" "}
{stat.usedValue} / {stat.maxUsedValue}{" "}
</Text>
{stat.capacityUnit && (
<Text component="span" ml={4}>
{stat.capacityUnit}
</Text>
)}
</>
)}
</Text>
<Text fz="sm" c="dimmed">
{isRTL ? `%${stat.percentageValue}` : `${stat.percentageValue}%`}
</Text>
</Group>
<Progress value={stat.percentageValue} mt={5} color={getProgressBarColor(stat.percentageValue)} />
</div>
);
})}
</Paper>
);
}
function getProgressBarColor(value: number): string {
if (value > 50 && value < 65) {
return "yellow";
} else if (value >= 65) {
return "red";
}
return "blue";
}
@@ -0,0 +1,21 @@
import React from "react";
import { IconCpu, IconCube, IconDeviceDesktopAnalytics } from "@tabler/icons-react";
import type { KubernetesCapacityType } from "@homarr/definitions";
const resourceIcons = {
CPU: IconCpu,
Memory: IconDeviceDesktopAnalytics,
Pods: IconCube,
} satisfies Record<KubernetesCapacityType, React.ComponentType<{ size: number; stroke: number }>>;
interface ResourceIconProps {
type: KubernetesCapacityType;
size?: number;
stroke?: number;
}
export const ResourceIcon: React.FC<ResourceIconProps> = ({ type, size = 32, stroke = 1.5 }) => {
const Icon = resourceIcons[type];
return <Icon size={size} stroke={stroke} />;
};
@@ -0,0 +1,10 @@
.cardContainer {
transition:
box-shadow 150ms ease,
transform 100ms ease;
@mixin hover {
box-shadow: var(--mantine-shadow-md);
transform: scale(1.02);
}
}
@@ -0,0 +1,37 @@
import React from "react";
import Image from "next/image";
import Link from "next/link";
import { Card, Group, Text } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
import type { KubernetesLabelResourceType } from "@homarr/definitions";
import { useI18n } from "@homarr/translation/client";
import classes from "./resource-tile.module.css";
interface ResourceTileProps {
count: number;
label: KubernetesLabelResourceType;
}
export function ResourceTile(props: ResourceTileProps) {
const t = useI18n();
return (
<Card
withBorder
component={Link}
href={`/manage/tools/kubernetes/${props.label}`}
className={classes.cardContainer}
>
<Group justify="space-between" wrap="nowrap">
<Image src={`/images/kubernetes/${props.label}.svg`} alt={props.label} width={64} height={64} />
<Group gap="xs">
<Text size="xl" fw={700} tt="capitalize">
{props.count} {t(`kubernetes.cluster.resources.${props.label}`)}
</Text>
<IconArrowRight />
</Group>
</Group>
</Card>
);
}
@@ -0,0 +1,74 @@
"use client";
import React from "react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import type { KubernetesBaseResource } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface ConfigMapsTableComponentProps {
initialConfigMaps: RouterOutputs["kubernetes"]["configMaps"]["getConfigMaps"];
}
const createColumns = (
t: ScopedTranslationFunction<"kubernetes.configmaps">,
): MRT_ColumnDef<KubernetesBaseResource>[] => [
{
accessorKey: "name",
header: t("field.name.label"),
enableClickToCopy: true,
},
{
accessorKey: "namespace",
header: t("field.namespace.label"),
enableClickToCopy: true,
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function ConfigmapsTable(initialData: ConfigMapsTableComponentProps) {
const tConfigMaps = useScopedI18n("kubernetes.configmaps");
const { data } = clientApi.kubernetes.configMaps.getConfigMaps.useQuery(undefined, {
initialData: initialData.initialConfigMaps,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true },
mantineSearchTextInputProps: {
placeholder: tConfigMaps("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
columns: createColumns(tConfigMaps),
});
return <MantineReactTable table={table} />;
}
@@ -0,0 +1,30 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { ConfigmapsTable } from "~/app/[locale]/manage/tools/kubernetes/configmaps/configmaps-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function ConfigMapsPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const configMaps = await api.kubernetes.configMaps.getConfigMaps();
const tConfigMaps = await getScopedI18n("kubernetes.configmaps");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tConfigMaps("label")}</Title>
<ConfigmapsTable initialConfigMaps={configMaps} />
</Stack>
</>
);
}
@@ -0,0 +1,107 @@
"use client";
import React from "react";
import { Anchor, Flex } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { createId } from "@homarr/db/client";
import type { KubernetesIngress } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface IngressesTableComponentProps {
initialIngresses: RouterOutputs["kubernetes"]["ingresses"]["getIngresses"];
}
const createColumns = (t: ScopedTranslationFunction<"kubernetes.ingresses">): MRT_ColumnDef<KubernetesIngress>[] => [
{
accessorKey: "name",
header: t("field.name.label"),
enableClickToCopy: true,
},
{
accessorKey: "namespace",
header: t("field.namespace.label"),
enableClickToCopy: true,
},
{
accessorKey: "className",
header: t("field.className.label"),
enableClickToCopy: true,
},
{
accessorKey: "rulesAndPaths",
header: t("field.rulesAndPaths.label"),
Cell({ cell }) {
const getAbsoluteUrl = (host: string) =>
host.startsWith("http://") || host.startsWith("https://") ? host : `https://${host}`;
return (
<>
{cell.row.original.rulesAndPaths.map((ruleAndPaths) => (
<div key={ruleAndPaths.host}>
<Flex align="flex-end">
<Anchor href={getAbsoluteUrl(ruleAndPaths.host)} target="_blank">
{getAbsoluteUrl(ruleAndPaths.host)}
</Anchor>
<IconArrowRight size={22} stroke={2} />
</Flex>
{ruleAndPaths.paths.map((path) => (
<div key={createId()}>
{path.serviceName}:{path.port}
</div>
))}
</div>
))}
</>
);
},
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function IngressesTable(initialData: IngressesTableComponentProps) {
const tIngresses = useScopedI18n("kubernetes.ingresses");
const { data } = clientApi.kubernetes.ingresses.getIngresses.useQuery(undefined, {
initialData: initialData.initialIngresses,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true },
mantineSearchTextInputProps: {
placeholder: tIngresses("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
columns: createColumns(tIngresses),
});
return <MantineReactTable table={table} />;
}
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { IngressesTable } from "~/app/[locale]/manage/tools/kubernetes/ingresses/ingresses-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function NamespacesPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const ingresses = await api.kubernetes.ingresses.getIngresses();
const tIngresses = await getScopedI18n("kubernetes.ingresses");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tIngresses("label")}</Title>
<IngressesTable initialIngresses={ingresses} />
</Stack>
</>
);
}
@@ -0,0 +1,91 @@
"use client";
import React from "react";
import { Badge, rem } from "@mantine/core";
import { IconCircleDashedCheck, IconHeartBroken } from "@tabler/icons-react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import type { KubernetesNamespace } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface NamespacesTableComponentProps {
initialNamespaces: RouterOutputs["kubernetes"]["namespaces"]["getNamespaces"];
}
const createColumns = (t: ScopedTranslationFunction<"kubernetes.namespaces">): MRT_ColumnDef<KubernetesNamespace>[] => [
{
accessorKey: "status",
header: t("field.state.label"),
Cell({ cell }) {
const checkIcon = <IconCircleDashedCheck style={{ width: rem(12), height: rem(12) }} />;
const downIcon = <IconHeartBroken style={{ width: rem(12), height: rem(12) }} />;
const badgeKubernetesNamespaceStatusColor = cell.row.original.status === "Active" ? "green" : "yellow";
const badgeKubernetesNamespaceStatusIcon = cell.row.original.status === "Active" ? checkIcon : downIcon;
return (
<Badge
leftSection={badgeKubernetesNamespaceStatusIcon}
color={badgeKubernetesNamespaceStatusColor}
variant="light"
>
{cell.row.original.status}
</Badge>
);
},
},
{
accessorKey: "name",
header: t("field.name.label"),
enableClickToCopy: true,
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function NamespacesTable(initialData: NamespacesTableComponentProps) {
const tNamespaces = useScopedI18n("kubernetes.namespaces");
const { data } = clientApi.kubernetes.namespaces.getNamespaces.useQuery(undefined, {
initialData: initialData.initialNamespaces,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true },
mantineSearchTextInputProps: {
placeholder: tNamespaces("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
columns: createColumns(tNamespaces),
});
return <MantineReactTable table={table} />;
}
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { NamespacesTable } from "~/app/[locale]/manage/tools/kubernetes/namespaces/namespaces-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function NamespacesPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const namespaces = await api.kubernetes.namespaces.getNamespaces();
const tNamespaces = await getScopedI18n("kubernetes.namespaces");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tNamespaces("label")}</Title>
<NamespacesTable initialNamespaces={namespaces} />
</Stack>
</>
);
}
@@ -0,0 +1,132 @@
"use client";
import React from "react";
import { Badge, rem, RingProgress, Text } from "@mantine/core";
import { IconCircleDashedCheck, IconHeartBroken } from "@tabler/icons-react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import type { KubernetesNode } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface NodesListComponentProps {
initialNodes: RouterOutputs["kubernetes"]["nodes"]["getNodes"];
}
const createColumns = (t: ScopedTranslationFunction<"kubernetes.nodes">): MRT_ColumnDef<KubernetesNode>[] => [
{
accessorKey: "status",
header: t("field.state.label"),
Cell({ cell }) {
const checkIcon = <IconCircleDashedCheck style={{ width: rem(12), height: rem(12) }} />;
const downIcon = <IconHeartBroken style={{ width: rem(12), height: rem(12) }} />;
const badgeKubernetesNodeStatusColor = cell.row.original.status === "Ready" ? "green" : "red";
const badgeKubernetesNodeStatusIcon = cell.row.original.status === "Ready" ? checkIcon : downIcon;
return (
<Badge leftSection={badgeKubernetesNodeStatusIcon} color={badgeKubernetesNodeStatusColor} variant="light">
{cell.row.original.status}
</Badge>
);
},
},
{
accessorKey: "name",
header: t("field.name.label"),
enableClickToCopy: true,
},
{
accessorKey: "allocatableCpuPercentage",
header: t("field.cpu.label"),
Cell({ cell }) {
return getRingProgress(cell.row.original.allocatableCpuPercentage);
},
},
{
accessorKey: "allocatableRamPercentage",
header: t("field.memory.label"),
Cell({ cell }) {
return getRingProgress(cell.row.original.allocatableRamPercentage);
},
},
{
accessorKey: "operatingSystem",
header: t("field.operatingSystem.label"),
},
{
accessorKey: "podsCount",
header: t("field.pods.label"),
},
{
accessorKey: "architecture",
header: t("field.architecture.label"),
},
{
accessorKey: "kubernetesVersion",
header: t("field.kubernetesVersion.label"),
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function NodesTable(initialData: NodesListComponentProps) {
const tNodes = useScopedI18n("kubernetes.nodes");
const { data } = clientApi.kubernetes.nodes.getNodes.useQuery(undefined, {
initialData: initialData.initialNodes,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true },
mantineSearchTextInputProps: {
placeholder: tNodes("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
columns: createColumns(tNodes),
});
return <MantineReactTable table={table} />;
}
function getRingProgress(value: number) {
return (
<RingProgress
size={70}
roundCaps
thickness={7}
sections={[{ value, color: "blue" }]}
label={
<Text c="blue" fw={400} ta="center" size="md">
{value}%
</Text>
}
/>
);
}
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { NodesTable } from "~/app/[locale]/manage/tools/kubernetes/nodes/nodes-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function NodesPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const nodes = await api.kubernetes.nodes.getNodes();
const tNodes = await getScopedI18n("kubernetes.nodes");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tNodes("label")}</Title>
<NodesTable initialNodes={nodes} />
</Stack>
</>
);
}
@@ -0,0 +1,21 @@
import { notFound } from "next/navigation";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { ClusterDashboard } from "~/app/[locale]/manage/tools/kubernetes/cluster-dashboard/cluster-dashboard";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function KubernetesPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
return (
<>
<DynamicBreadcrumb />
<ClusterDashboard />
</>
);
}
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { PodsTable } from "~/app/[locale]/manage/tools/kubernetes/pods/pods-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function PodsPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const pods = await api.kubernetes.pods.getPods();
const tPods = await getScopedI18n("kubernetes.pods");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tPods("label")}</Title>
<PodsTable initialPods={pods} />
</Stack>
</>
);
}
@@ -0,0 +1,82 @@
"use client";
import React from "react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import type { KubernetesPod } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface PodsTableComponentProps {
initialPods: RouterOutputs["kubernetes"]["pods"]["getPods"];
}
const createColumns = (t: ScopedTranslationFunction<"kubernetes.pods">): MRT_ColumnDef<KubernetesPod>[] => [
{
accessorKey: "name",
header: t("field.name.label"),
},
{
accessorKey: "namespace",
header: t("field.namespace.label"),
},
{
accessorKey: "image",
header: t("field.image.label"),
},
{
accessorKey: "applicationType",
header: t("field.applicationType.label"),
},
{
accessorKey: "status",
header: t("field.status.label"),
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function PodsTable(initialData: PodsTableComponentProps) {
const tPods = useScopedI18n("kubernetes.pods");
const { data } = clientApi.kubernetes.pods.getPods.useQuery(undefined, {
initialData: initialData.initialPods,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true, expanded: true },
mantineSearchTextInputProps: {
placeholder: tPods("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
enableGrouping: true,
columns: createColumns(tPods),
});
return <MantineReactTable table={table} />;
}
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { SecretsTable } from "~/app/[locale]/manage/tools/kubernetes/secrets/secrets-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function SecretsPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const secrets = await api.kubernetes.secrets.getSecrets();
const tSecrets = await getScopedI18n("kubernetes.secrets");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tSecrets("label")}</Title>
<SecretsTable initialSecrets={secrets} />
</Stack>
</>
);
}
@@ -0,0 +1,77 @@
"use client";
import React from "react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import type { KubernetesSecret } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface SecretsTableComponentProps {
initialSecrets: RouterOutputs["kubernetes"]["secrets"]["getSecrets"];
}
const createColumns = (t: ScopedTranslationFunction<"kubernetes.secrets">): MRT_ColumnDef<KubernetesSecret>[] => [
{
accessorKey: "name",
header: t("field.name.label"),
enableClickToCopy: true,
},
{
accessorKey: "namespace",
header: t("field.namespace.label"),
enableClickToCopy: true,
},
{
accessorKey: "type",
header: t("field.type.label"),
enableClickToCopy: true,
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function SecretsTable(initialData: SecretsTableComponentProps) {
const tSecrets = useScopedI18n("kubernetes.secrets");
const { data } = clientApi.kubernetes.secrets.getSecrets.useQuery(undefined, {
initialData: initialData.initialSecrets,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true },
mantineSearchTextInputProps: {
placeholder: tSecrets("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
columns: createColumns(tSecrets),
});
return <MantineReactTable table={table} />;
}
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { ServicesTable } from "~/app/[locale]/manage/tools/kubernetes/services/services-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function ServicesPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const services = await api.kubernetes.services.getServices();
const tServices = await getScopedI18n("kubernetes.services");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tServices("label")}</Title>
<ServicesTable initialServices={services} />
</Stack>
</>
);
}
@@ -0,0 +1,95 @@
"use client";
import React from "react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import { createId } from "@homarr/db/client";
import type { KubernetesService } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface ServicesTableComponentProps {
initialServices: RouterOutputs["kubernetes"]["services"]["getServices"];
}
const createColumns = (t: ScopedTranslationFunction<"kubernetes.services">): MRT_ColumnDef<KubernetesService>[] => [
{
accessorKey: "name",
header: t("field.name.label"),
enableClickToCopy: true,
},
{
accessorKey: "namespace",
header: t("field.namespace.label"),
enableClickToCopy: true,
},
{
accessorKey: "type",
header: t("field.type.label"),
},
{
accessorKey: "ports",
header: t("field.ports.label"),
Cell({ cell }) {
return cell.row.original.ports?.map((port) => <div key={createId()}>{port}</div>);
},
},
{
accessorKey: "targetPorts",
header: t("field.targetPorts.label"),
Cell({ cell }) {
return cell.row.original.targetPorts?.map((targetPort) => <div key={createId()}>{targetPort}</div>);
},
},
{
accessorKey: "clusterIP",
header: t("field.clusterIP.label"),
enableClickToCopy: true,
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function ServicesTable(initialData: ServicesTableComponentProps) {
const tServices = useScopedI18n("kubernetes.services");
const { data } = clientApi.kubernetes.services.getServices.useQuery(undefined, {
initialData: initialData.initialServices,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true },
mantineSearchTextInputProps: {
placeholder: tServices("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
columns: createColumns(tServices),
});
return <MantineReactTable table={table} />;
}
@@ -0,0 +1,29 @@
import { notFound } from "next/navigation";
import { Stack, Title } from "@mantine/core";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { env } from "@homarr/docker/env";
import { getScopedI18n } from "@homarr/translation/server";
import { VolumesTable } from "~/app/[locale]/manage/tools/kubernetes/volumes/volumes-table";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
export default async function VolumesPage() {
const session = await auth();
if (!(session?.user.permissions.includes("admin") && env.ENABLE_KUBERNETES)) {
notFound();
}
const volumes = await api.kubernetes.volumes.getVolumes();
const tVolumes = await getScopedI18n("kubernetes.volumes");
return (
<>
<DynamicBreadcrumb />
<Stack>
<Title order={1}>{tVolumes("label")}</Title>
<VolumesTable initialVolumes={volumes} />
</Stack>
</>
);
}
@@ -0,0 +1,101 @@
"use client";
import React from "react";
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client";
import type { KubernetesVolume } from "@homarr/definitions";
import type { ScopedTranslationFunction } from "@homarr/translation";
import { useScopedI18n } from "@homarr/translation/client";
import { useTranslatedMantineReactTable } from "@homarr/ui/hooks";
dayjs.extend(relativeTime);
interface VolumesTableComponentProps {
initialVolumes: RouterOutputs["kubernetes"]["volumes"]["getVolumes"];
}
const createColumns = (t: ScopedTranslationFunction<"kubernetes.volumes">): MRT_ColumnDef<KubernetesVolume>[] => [
{
accessorKey: "status",
header: t("field.status.label"),
},
{
accessorKey: "name",
header: t("field.name.label"),
enableClickToCopy: true,
},
{
accessorKey: "namespace",
header: t("field.namespace.label"),
enableClickToCopy: true,
},
{
accessorKey: "storage",
header: t("field.storage.label"),
},
{
accessorKey: "storageClassName",
header: t("field.storageClassName.label"),
enableClickToCopy: true,
},
{
accessorKey: "volumeMode",
header: t("field.volumeMode.label"),
},
{
accessorKey: "volumeName",
header: t("field.volumeName.label"),
enableClickToCopy: true,
},
{
accessorKey: "accessModes",
header: t("field.accessModes.label"),
Cell({ cell }) {
return cell.row.original.accessModes.map((accessMode) => <div key={accessMode}>{accessMode}</div>);
},
},
{
accessorKey: "creationTimestamp",
header: t("field.creationTimestamp.label"),
Cell: ({ row }) => dayjs(row.original.creationTimestamp).fromNow(false),
},
];
export function VolumesTable(initialData: VolumesTableComponentProps) {
const tVolumes = useScopedI18n("kubernetes.volumes");
const { data } = clientApi.kubernetes.volumes.getVolumes.useQuery(undefined, {
initialData: initialData.initialVolumes,
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const table = useTranslatedMantineReactTable({
data,
enableDensityToggle: false,
enableColumnActions: false,
enableColumnFilters: false,
enablePagination: false,
enableRowSelection: true,
positionToolbarAlertBanner: "top",
enableTableFooter: false,
enableBottomToolbar: false,
positionGlobalFilter: "right",
initialState: { density: "xs", showGlobalFilter: true },
mantineSearchTextInputProps: {
placeholder: tVolumes("table.search", { count: String(data.length) }),
style: { minWidth: 300 },
autoFocus: true,
},
columns: createColumns(tVolumes),
});
return <MantineReactTable table={table} />;
}
@@ -66,15 +66,17 @@ export const JobsList = ({ initialJobs }: JobsListProps) => {
{job.status && <TimeAgo timestamp={job.status.lastExecutionTimestamp} />}
</Stack>
<ActionIcon
onClick={() => handleJobTrigger(job)}
disabled={job.status?.status === "running"}
variant={"default"}
size={"xl"}
radius={"xl"}
>
<IconPlayerPlay stroke={1.5} />
</ActionIcon>
{!job.job.preventManualExecution && (
<ActionIcon
onClick={() => handleJobTrigger(job)}
disabled={job.status?.status === "running"}
variant={"default"}
size={"xl"}
radius={"xl"}
>
<IconPlayerPlay stroke={1.5} />
</ActionIcon>
)}
</Group>
</Card>
))}
@@ -9,7 +9,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { userChangeHomeBoardsSchema } from "@homarr/validation/user";
import type { Board } from "~/app/[locale]/boards/_types";
import { BoardSelect } from "~/components/board/board-select";
@@ -40,7 +40,7 @@ export const ChangeHomeBoardForm = ({ user, boardsData }: ChangeHomeBoardFormPro
});
},
});
const form = useZodForm(validation.user.changeHomeBoards, {
const form = useZodForm(userChangeHomeBoardsSchema, {
initialValues: {
homeBoardId: user.homeBoardId,
mobileHomeBoardId: user.mobileHomeBoardId,
@@ -73,7 +73,7 @@ export const ChangeHomeBoardForm = ({ user, boardsData }: ChangeHomeBoardFormPro
/>
<Group justify="end">
<Button type="submit" color="teal" loading={isPending}>
<Button type="submit" loading={isPending}>
{t("common.action.save")}
</Button>
</Group>
@@ -82,4 +82,4 @@ export const ChangeHomeBoardForm = ({ user, boardsData }: ChangeHomeBoardFormPro
);
};
type FormType = z.infer<typeof validation.user.changeHomeBoards>;
type FormType = z.infer<typeof userChangeHomeBoardsSchema>;
@@ -9,7 +9,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { userChangeSearchPreferencesSchema } from "@homarr/validation/user";
interface ChangeSearchPreferencesFormProps {
user: RouterOutputs["user"]["getById"];
@@ -37,7 +37,7 @@ export const ChangeSearchPreferencesForm = ({ user, searchEnginesData }: ChangeS
});
},
});
const form = useZodForm(validation.user.changeSearchPreferences, {
const form = useZodForm(userChangeSearchPreferencesSchema, {
initialValues: {
defaultSearchEngineId: user.defaultSearchEngineId,
openInNewTab: user.openSearchInNewTab,
@@ -66,7 +66,7 @@ export const ChangeSearchPreferencesForm = ({ user, searchEnginesData }: ChangeS
/>
<Group justify="end">
<Button type="submit" color="teal" loading={isPending}>
<Button type="submit" loading={isPending}>
{t("common.action.save")}
</Button>
</Group>
@@ -75,4 +75,4 @@ export const ChangeSearchPreferencesForm = ({ user, searchEnginesData }: ChangeS
);
};
type FormType = z.infer<typeof validation.user.changeSearchPreferences>;
type FormType = z.infer<typeof userChangeSearchPreferencesSchema>;
@@ -28,7 +28,8 @@ export const DeleteUserButton = ({ user }: DeleteUserButtonProps) => {
() =>
openConfirmModal({
title: t("user.action.delete.label"),
children: t("user.action.delete.confirm", { username: user.name }),
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
children: t("user.action.delete.confirm", { username: user.name! }),
// eslint-disable-next-line no-restricted-syntax
async onConfirm() {
await mutateUserDeletionAsync({
@@ -12,7 +12,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { userFirstDayOfWeekSchema } from "@homarr/validation/user";
dayjs.extend(localeData);
@@ -42,7 +42,7 @@ export const FirstDayOfWeek = ({ user }: FirstDayOfWeekProps) => {
});
},
});
const form = useZodForm(validation.user.firstDayOfWeek, {
const form = useZodForm(userFirstDayOfWeekSchema, {
initialValues: {
firstDayOfWeek: user.firstDayOfWeek as DayOfWeek,
},
@@ -71,7 +71,7 @@ export const FirstDayOfWeek = ({ user }: FirstDayOfWeekProps) => {
</Radio.Group>
<Group justify="end">
<Button type="submit" color="teal" loading={isPending}>
<Button type="submit" loading={isPending}>
{t("common.action.save")}
</Button>
</Group>
@@ -80,4 +80,4 @@ export const FirstDayOfWeek = ({ user }: FirstDayOfWeekProps) => {
);
};
type FormType = z.infer<typeof validation.user.firstDayOfWeek>;
type FormType = z.infer<typeof userFirstDayOfWeekSchema>;
@@ -9,7 +9,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { userPingIconsEnabledSchema } from "@homarr/validation/user";
interface PingIconsEnabledProps {
user: RouterOutputs["user"]["getById"];
@@ -35,7 +35,7 @@ export const PingIconsEnabled = ({ user }: PingIconsEnabledProps) => {
});
},
});
const form = useZodForm(validation.user.pingIconsEnabled, {
const form = useZodForm(userPingIconsEnabledSchema, {
initialValues: {
pingIconsEnabled: user.pingIconsEnabled,
},
@@ -57,7 +57,7 @@ export const PingIconsEnabled = ({ user }: PingIconsEnabledProps) => {
/>
<Group justify="end">
<Button type="submit" color="teal" loading={isPending}>
<Button type="submit" loading={isPending}>
{t("common.action.save")}
</Button>
</Group>
@@ -66,4 +66,4 @@ export const PingIconsEnabled = ({ user }: PingIconsEnabledProps) => {
);
};
type FormType = z.infer<typeof validation.user.pingIconsEnabled>;
type FormType = z.infer<typeof userPingIconsEnabledSchema>;
@@ -9,7 +9,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { userEditProfileSchema } from "@homarr/validation/user";
interface UserProfileFormProps {
user: RouterOutputs["user"]["getById"];
@@ -43,7 +43,7 @@ export const UserProfileForm = ({ user }: UserProfileFormProps) => {
});
},
});
const form = useZodForm(validation.user.editProfile.omit({ id: true }), {
const form = useZodForm(userEditProfileSchema.omit({ id: true }), {
initialValues: {
name: user.name ?? "",
email: user.email ?? "",
@@ -81,7 +81,7 @@ export const UserProfileForm = ({ user }: UserProfileFormProps) => {
{isProviderCredentials && (
<Group justify="end">
<Button type="submit" color="teal" disabled={!form.isDirty()} loading={isPending}>
<Button type="submit" disabled={!form.isDirty()} loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
@@ -41,7 +41,8 @@ export async function generateMetadata(props: Props) {
const t = await getScopedI18n("management.page.user.edit");
return {
title: createMetaTitle(t("metaTitle", { username: user.name })),
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
title: createMetaTitle(t("metaTitle", { username: user.name! })),
};
}
@@ -117,15 +118,13 @@ export default async function EditUserPage(props: Props) {
<PingIconsEnabled user={user} />
</Stack>
{isCredentialsUser && (
<DangerZoneRoot>
<DangerZoneItem
label={t("user.action.delete.label")}
description={t("user.action.delete.description")}
action={<DeleteUserButton user={user} />}
/>
</DangerZoneRoot>
)}
<DangerZoneRoot>
<DangerZoneItem
label={t("user.action.delete.label")}
description={t("user.action.delete.description")}
action={<DeleteUserButton user={user} />}
/>
</DangerZoneRoot>
</Stack>
);
}
@@ -10,7 +10,7 @@ import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { CustomPasswordInput } from "@homarr/ui";
import { validation } from "@homarr/validation";
import { userChangePasswordSchema } from "@homarr/validation/user";
interface ChangePasswordFormProps {
user: RouterOutputs["user"]["getById"];
@@ -34,7 +34,7 @@ export const ChangePasswordForm = ({ user }: ChangePasswordFormProps) => {
});
},
});
const form = useZodForm(validation.user.changePassword, {
const form = useZodForm(userChangePasswordSchema, {
initialValues: {
/* Require previous password if the current user want's to change his password */
previousPassword: session?.user.id === user.id ? "" : "_",
@@ -85,7 +85,7 @@ export const ChangePasswordForm = ({ user }: ChangePasswordFormProps) => {
/>
<Group justify="end">
<Button type="submit" color="teal" loading={isPending}>
<Button type="submit" loading={isPending}>
{t("common.action.confirm")}
</Button>
</Group>
@@ -27,8 +27,8 @@ import { useModalAction } from "@homarr/modals";
import { showErrorNotification } from "@homarr/notifications";
import { useI18n, useScopedI18n } from "@homarr/translation/client";
import { CustomPasswordInput, UserAvatar } from "@homarr/ui";
import { validation } from "@homarr/validation";
import { createCustomErrorParams } from "@homarr/validation/form";
import { createCustomErrorParams } from "@homarr/validation/form/i18n";
import { userPasswordSchema } from "@homarr/validation/user";
import { GroupSelectModal } from "~/components/access/group-select-modal";
import { StepperNavigationComponent } from "./stepper-navigation";
@@ -84,7 +84,7 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC
const securityForm = useZodForm(
z
.object({
password: validation.user.password,
password: userPasswordSchema,
confirmPassword: z.string(),
})
.refine((data) => data.password === data.confirmPassword, {
@@ -8,7 +8,7 @@ import { revalidatePathActionAsync } from "@homarr/common/client";
import { useZodForm } from "@homarr/form";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation";
import { groupUpdateSchema } from "@homarr/validation/group";
interface RenameGroupFormProps {
group: {
@@ -21,7 +21,7 @@ interface RenameGroupFormProps {
export const RenameGroupForm = ({ group, disabled }: RenameGroupFormProps) => {
const t = useI18n();
const { mutate, isPending } = clientApi.group.updateGroup.useMutation();
const form = useZodForm(validation.group.update.pick({ name: true }), {
const form = useZodForm(groupUpdateSchema.pick({ name: true }), {
initialValues: {
name: group.name,
},
@@ -68,7 +68,7 @@ export const RenameGroupForm = ({ group, disabled }: RenameGroupFormProps) => {
{!disabled && (
<Group justify="end">
<Button type="submit" color="teal" loading={isPending}>
<Button type="submit" loading={isPending}>
{t("common.action.saveChanges")}
</Button>
</Group>
Loaded 100 of 568 files, more files were not shown because too many files have changed in this diff. Show more