From 64dccec3627f293a9634a2c63ecef8c6e2c7d0da Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 16:46:40 +0000 Subject: [PATCH 1/8] chore(deps): update dependency oxfmt to ^0.51.0 (#5799) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 164 ++++++++++++++++++++++---------------------- pnpm-workspace.yaml | 2 +- 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0d5f3f600..a839b42a3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -412,8 +412,8 @@ catalogs: specifier: ^5.0.5 version: 5.0.5 oxfmt: - specifier: ^0.49.0 - version: 0.49.0 + specifier: ^0.51.0 + version: 0.51.0 oxlint: specifier: ^1.66.0 version: 1.66.0 @@ -609,7 +609,7 @@ importers: version: 2.2.3 oxfmt: specifier: 'catalog:' - version: 0.49.0 + version: 0.51.0 oxlint: specifier: 'catalog:' version: 1.66.0 @@ -4007,124 +4007,124 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@oxfmt/binding-android-arm-eabi@0.49.0': - resolution: {integrity: sha512-HbifJ84prIh9+55CTPAU35JdRQrwg47y16cGerCC+iejSKOuHXYo2WDql6l7cQlzrYVtc3f4UWY+dBj2lRmOeA==} + '@oxfmt/binding-android-arm-eabi@0.51.0': + resolution: {integrity: sha512-Ni0sCqg5CIHaLIYFGj+ncbcumylvNC6FE4rfD0KfdmnWHbPJ+zev0qZCXKxy2hFVa0fYRK0yPzf5nzPbkZou7g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxfmt/binding-android-arm64@0.49.0': - resolution: {integrity: sha512-Ef7SKJqAaH2d7E6eXZZa2OffIShbhFMxnGK0zd93p4qiyTJr75B0qf7lrPD+qQOwcf04BrjYJ0JUxq8d5+yZwg==} + '@oxfmt/binding-android-arm64@0.51.0': + resolution: {integrity: sha512-eu5lAZjuo0KAkp+M24EhDqfOwA8owQ8d7wyBlOUUGRbDLHpU3IRlDHp8Dif+YqGlxs6jra7yS6WQu/NkPhAxeg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxfmt/binding-darwin-arm64@0.49.0': - resolution: {integrity: sha512-8x5DN9CsFfb432sHa9NyqX5XisGUdA53LPEGSdv/VniS+v4uEOR8Orv7A9QSB98Xxgp0t6r31DzQA/wpIobGqQ==} + '@oxfmt/binding-darwin-arm64@0.51.0': + resolution: {integrity: sha512-6LsUNIdURhhcIfIn8+xsOb61mSTa9msAHTeSGx9Jf4rsP/gN8PGCF+SKWPAQZbND2w/WBkqQ6303jqEEIXzMdQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxfmt/binding-darwin-x64@0.49.0': - resolution: {integrity: sha512-e0+DSVzk4ewhMVKNYDaRTmP81jNMBWR1X9al0cVKWS+hDM/dElNqD5zjTOCuLOZc4oOdp2Gx2ldrVL+yYo9TZQ==} + '@oxfmt/binding-darwin-x64@0.51.0': + resolution: {integrity: sha512-9aUMGmVxdHjYMsEAW1tNRoieTJXlVNDFkRvIR1J7LttJXWjVYCu2ekclLij2KJtxBxSQOYSHd12ME/adVGVbZg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxfmt/binding-freebsd-x64@0.49.0': - resolution: {integrity: sha512-W+mjtYtrQvFbXT/uNT+221OBhGRZ8UqNsLxjTWsjZ4GsQnRdvRC/N2NCK86BcamWr7lsTxwpwN3PULnr78sgcQ==} + '@oxfmt/binding-freebsd-x64@0.51.0': + resolution: {integrity: sha512-mkY1nhZTqYb+NHaAWxOCKISN6FwdrwMNsu17vTUA3wzUV2VJ+Paq15ZokRcsMU/2PUdHO73prxyeJpjXQ3MPpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxfmt/binding-linux-arm-gnueabihf@0.49.0': - resolution: {integrity: sha512-Rtv6UevV7czDlLqil+NZUe4d8gs8jQo/zScSpumwyf7I+fSdLc+hc8AF3MQC7ymxSMMD9+vfiqQlsIf7wOAzXA==} + '@oxfmt/binding-linux-arm-gnueabihf@0.51.0': + resolution: {integrity: sha512-wtFwNwE4+YCNuPaWoGDZeGsKvD6D1YSUNBJNn/rJBh7CrDBThFE+TBI5kY7vRW9rIOQRsbW2IpyyL3Du4Zqwiw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm-musleabihf@0.49.0': - resolution: {integrity: sha512-sBi+8C/Q/MdKa5FL8ibAUCdhFBGFH7HFN/Qoyd5xQbZ/0ky3NMPpKfIBpaH0lhK2dXkGLczVQUoZ+xuNSerCdQ==} + '@oxfmt/binding-linux-arm-musleabihf@0.51.0': + resolution: {integrity: sha512-rnOaNx86G7iRKM6lsCIQMux0SMGNC/TEbFR+r7lpruJ12bnrIWgxd5w1PLqOvgR9r8ZJbpK/zfRKctJnh8/Jfg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxfmt/binding-linux-arm64-gnu@0.49.0': - resolution: {integrity: sha512-JIfWenFhlzx+O8YygyZhoHFzTsdgDhxhbDRnE2iJLnnM5pWKScFvPECO2vOlA7JqJ/9S1g3uzEKuRCkHFwTjvA==} + '@oxfmt/binding-linux-arm64-gnu@0.51.0': + resolution: {integrity: sha512-jOgDzSqWcICGRjsp4mc08FxKMN8vzP2Kgs4E0d2HUP99F+nJDQKklRV4Zuj+0gcBgjrzx2CbpqaIdUVPepCojA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-arm64-musl@0.49.0': - resolution: {integrity: sha512-iNzkMPG18jPkwBOZ4/HEjwqfzAjq4RrUQ0CgId/fC1ENvYD5jLVAaU/gWgpiqP1ys07kxSsSggDd1fp3E7mQHw==} + '@oxfmt/binding-linux-arm64-musl@0.51.0': + resolution: {integrity: sha512-KBUCdrH5bwVrAvI9gU/1S55oH6fzXjr++J/oVocdu7bYTks1l7DNNT+rLd/1TDdAEjObGwmfWamn7LC1m8A0DQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-ppc64-gnu@0.49.0': - resolution: {integrity: sha512-BPHA/NN3LvoIXiid+iz3BHt5V0Rzx0tXAqRUovwE1NsbDaLG9e8mtv7evDGRIkVQacqTDBv0XL25THHsxSJosQ==} + '@oxfmt/binding-linux-ppc64-gnu@0.51.0': + resolution: {integrity: sha512-NapfjYsABFqTJ1Dn9Efq6sN5esaHconVKwVLbDGNQLrwpOx/g17mkwErHzU72PutL67nf3wNAkbq122H+zLxag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-gnu@0.49.0': - resolution: {integrity: sha512-3Eroshe+s69htC9JIL0+zLGQczLtRKezkMhwqQC21VC5Z/fuLvzLfbAOLgJLUq601H8gDYjy7deYycfOBjCvWg==} + '@oxfmt/binding-linux-riscv64-gnu@0.51.0': + resolution: {integrity: sha512-5dlDt1dUZCVi6elIhiK1PWg9wpTzTcIuj0IZnSurvIoMrhOWqqTcc1dSTxcSkNaBZhfsNqRZdINI1zAgbKkJNQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-musl@0.49.0': - resolution: {integrity: sha512-fnaERGgsxGm0lKAmO72EYR4BA3qBnzBTJBTi6EtUMq1D4R7EexRBMU4voXnx4TXla3SEDl9x4uNp/18SbkPjGg==} + '@oxfmt/binding-linux-riscv64-musl@0.51.0': + resolution: {integrity: sha512-pgdWUJn0S5nulyiVdlFV8DzCUnGXkU99W5PSkkmbaZW+LrZBPxpezun4G0DDHbQaVYuJeCuKsXsGKGo77CkUTQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-s390x-gnu@0.49.0': - resolution: {integrity: sha512-rBwasMl1Uul1MCCeTGEFKnOTL7VUxHf+634jWStrQAbzpBJgd5Yz5m4F7exVCsoI8PHn57dNjssXagXLCLB5yA==} + '@oxfmt/binding-linux-s390x-gnu@0.51.0': + resolution: {integrity: sha512-2XTFUe97CbDGAI8vjwDfZ1HdakO0XIADyJ24idEg64SC4/K4in/OisXVnrW4NMK7I6TgC7EqRhC0Ln/nKhAemA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-gnu@0.49.0': - resolution: {integrity: sha512-BoC/F9xHe2y/deuBGA5Aw7bes07OD2gcL2wlpzTrfImR92vPP7S/k3LBTyspQZCNIVNdagkELcqKELwMLGIfAg==} + '@oxfmt/binding-linux-x64-gnu@0.51.0': + resolution: {integrity: sha512-kQ1OuCqqt/yyf0ZN9VFxW1/JnlgJgii3Dr7pWf9vNBvrX1hv6g39/+mc5oGRHRGJFZtl3zsGDWR9c5N2B/gwBw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-musl@0.49.0': - resolution: {integrity: sha512-umY6jFADAo/oztFKl8D/S6vSrG6oBpEskcentiRuz42kZVU2kfDXMWCYavxyZR2bwPjqkHpcHZ6EZFiH3Qj9ZA==} + '@oxfmt/binding-linux-x64-musl@0.51.0': + resolution: {integrity: sha512-ARTYqxHF475o96Gbn41hvSWSSRygPlRDXZZgZ9I2scU1y0qiWpCQyZCoefaQa0mwv+wwtZ+luS4YOzsRzM/izg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxfmt/binding-openharmony-arm64@0.49.0': - resolution: {integrity: sha512-J85zQMiw2pXiGPK+OusmDvSnJ/dgpgN7VgmB2zOBtgS8F+nsOUfSg9ZEBrwbQscjZ7tkPbm38CG4VF5f53MsiA==} + '@oxfmt/binding-openharmony-arm64@0.51.0': + resolution: {integrity: sha512-QiC1XrCl6a6BmqMzduO8hdIRMf1m44hCkt2Q68KWkTvUB/E7fd2iomyNh6KnnRca5w6eBrRAAtLFqTh+xjsjJA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxfmt/binding-win32-arm64-msvc@0.49.0': - resolution: {integrity: sha512-38K67XR++CoFFORDd4sMFwUVAnD6msYBdGTei+qvKGrRPO6S2PbrYPNL/eQQ1RgnnxOegNba0YQwg6uRkNcw6A==} + '@oxfmt/binding-win32-arm64-msvc@0.51.0': + resolution: {integrity: sha512-NC/hJb9dtU23Zf8L7IVK95xnFjiQ7AfcLO2l5pb69TDEr958qxrtnB2CveeeNSCBFNIkgaTCfd/vHNSoG78l9g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxfmt/binding-win32-ia32-msvc@0.49.0': - resolution: {integrity: sha512-rXVe0HICwQF0dBgbQtBCoYf8x/SidPIdhyQl+iPuJlV7suV+qDv7yUEB3wQ4qC3nOeNxz287SwFXKzyr0kWgEg==} + '@oxfmt/binding-win32-ia32-msvc@0.51.0': + resolution: {integrity: sha512-2C45za4Rj36n8YIbhRL1PQbxmXJYf81WEcAgvj5I4ptRROG+A+81hREEN5bmCHADE1UfYaN312U6tkILoZZy6w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxfmt/binding-win32-x64-msvc@0.49.0': - resolution: {integrity: sha512-gwWLwSEmBBfIK/Wh7GGd658161o4RKAvHWRaRQbJm571iQXGKfyr7UKsI1vsWvDlNLc30CxJDc8mMmCvJ/kczQ==} + '@oxfmt/binding-win32-x64-msvc@0.51.0': + resolution: {integrity: sha512-73RqdAuVKQTkjZIDw08JaDHUM4lav5Qu+CaPwg4QbbA7k8o7LEW0p3UsfZ/F8dsO/pwVYh3RzFcanwLRTTahbQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -7971,8 +7971,8 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - oxfmt@0.49.0: - resolution: {integrity: sha512-IAHFMdlJSWe+oAr65dx22UvjCtV9DBMisAuLnKpDqMQrctzCkGnj3QRwNHm0d+uwSWPalsDF8ZYLz9rh6nH2IQ==} + oxfmt@0.51.0: + resolution: {integrity: sha512-l/AoAnaEOV7Q5/Z9kHOMDehVJnCgYN7wRoooWCTUMBMi16BJhLZqd9cmCnwcVFfVlzkt53zK2KLPFNp8vSsoDg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -11208,61 +11208,61 @@ snapshots: '@open-draft/until@2.1.0': optional: true - '@oxfmt/binding-android-arm-eabi@0.49.0': + '@oxfmt/binding-android-arm-eabi@0.51.0': optional: true - '@oxfmt/binding-android-arm64@0.49.0': + '@oxfmt/binding-android-arm64@0.51.0': optional: true - '@oxfmt/binding-darwin-arm64@0.49.0': + '@oxfmt/binding-darwin-arm64@0.51.0': optional: true - '@oxfmt/binding-darwin-x64@0.49.0': + '@oxfmt/binding-darwin-x64@0.51.0': optional: true - '@oxfmt/binding-freebsd-x64@0.49.0': + '@oxfmt/binding-freebsd-x64@0.51.0': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.49.0': + '@oxfmt/binding-linux-arm-gnueabihf@0.51.0': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.49.0': + '@oxfmt/binding-linux-arm-musleabihf@0.51.0': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.49.0': + '@oxfmt/binding-linux-arm64-gnu@0.51.0': optional: true - '@oxfmt/binding-linux-arm64-musl@0.49.0': + '@oxfmt/binding-linux-arm64-musl@0.51.0': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.49.0': + '@oxfmt/binding-linux-ppc64-gnu@0.51.0': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.49.0': + '@oxfmt/binding-linux-riscv64-gnu@0.51.0': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.49.0': + '@oxfmt/binding-linux-riscv64-musl@0.51.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.49.0': + '@oxfmt/binding-linux-s390x-gnu@0.51.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.49.0': + '@oxfmt/binding-linux-x64-gnu@0.51.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.49.0': + '@oxfmt/binding-linux-x64-musl@0.51.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.49.0': + '@oxfmt/binding-openharmony-arm64@0.51.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.49.0': + '@oxfmt/binding-win32-arm64-msvc@0.51.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.49.0': + '@oxfmt/binding-win32-ia32-msvc@0.51.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.49.0': + '@oxfmt/binding-win32-x64-msvc@0.51.0': optional: true '@oxlint/binding-android-arm-eabi@1.66.0': @@ -15361,29 +15361,29 @@ snapshots: outvariant@1.4.3: optional: true - oxfmt@0.49.0: + oxfmt@0.51.0: dependencies: tinypool: 2.1.0 optionalDependencies: - '@oxfmt/binding-android-arm-eabi': 0.49.0 - '@oxfmt/binding-android-arm64': 0.49.0 - '@oxfmt/binding-darwin-arm64': 0.49.0 - '@oxfmt/binding-darwin-x64': 0.49.0 - '@oxfmt/binding-freebsd-x64': 0.49.0 - '@oxfmt/binding-linux-arm-gnueabihf': 0.49.0 - '@oxfmt/binding-linux-arm-musleabihf': 0.49.0 - '@oxfmt/binding-linux-arm64-gnu': 0.49.0 - '@oxfmt/binding-linux-arm64-musl': 0.49.0 - '@oxfmt/binding-linux-ppc64-gnu': 0.49.0 - '@oxfmt/binding-linux-riscv64-gnu': 0.49.0 - '@oxfmt/binding-linux-riscv64-musl': 0.49.0 - '@oxfmt/binding-linux-s390x-gnu': 0.49.0 - '@oxfmt/binding-linux-x64-gnu': 0.49.0 - '@oxfmt/binding-linux-x64-musl': 0.49.0 - '@oxfmt/binding-openharmony-arm64': 0.49.0 - '@oxfmt/binding-win32-arm64-msvc': 0.49.0 - '@oxfmt/binding-win32-ia32-msvc': 0.49.0 - '@oxfmt/binding-win32-x64-msvc': 0.49.0 + '@oxfmt/binding-android-arm-eabi': 0.51.0 + '@oxfmt/binding-android-arm64': 0.51.0 + '@oxfmt/binding-darwin-arm64': 0.51.0 + '@oxfmt/binding-darwin-x64': 0.51.0 + '@oxfmt/binding-freebsd-x64': 0.51.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.51.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.51.0 + '@oxfmt/binding-linux-arm64-gnu': 0.51.0 + '@oxfmt/binding-linux-arm64-musl': 0.51.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.51.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.51.0 + '@oxfmt/binding-linux-riscv64-musl': 0.51.0 + '@oxfmt/binding-linux-s390x-gnu': 0.51.0 + '@oxfmt/binding-linux-x64-gnu': 0.51.0 + '@oxfmt/binding-linux-x64-musl': 0.51.0 + '@oxfmt/binding-openharmony-arm64': 0.51.0 + '@oxfmt/binding-win32-arm64-msvc': 0.51.0 + '@oxfmt/binding-win32-ia32-msvc': 0.51.0 + '@oxfmt/binding-win32-x64-msvc': 0.51.0 oxlint@1.66.0: optionalDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c839909d4..0a6bdcd8d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -139,7 +139,7 @@ catalog: next-intl: 4.12.0 node-loader: ^2.1.0 octokit: ^5.0.5 - oxfmt: ^0.49.0 + oxfmt: ^0.51.0 oxlint: ^1.66.0 pg: ^8.21.0 postcss-preset-mantine: ^1.18.0 From fc12500b3e10f6167e5d1fecf7604b746aef365d Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 21:45:28 +0000 Subject: [PATCH 2/8] chore(deps): update tanstack-query monorepo to ^5.100.13 (#5803) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 84 ++++++++++++++++++++++----------------------- pnpm-workspace.yaml | 6 ++-- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a839b42a3..ce2c1c188 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -124,14 +124,14 @@ catalogs: specifier: ^3.44.0 version: 3.44.0 '@tanstack/react-query': - specifier: ^5.100.11 - version: 5.100.11 + specifier: ^5.100.13 + version: 5.100.14 '@tanstack/react-query-devtools': - specifier: ^5.100.11 - version: 5.100.11 + specifier: ^5.100.13 + version: 5.100.14 '@tanstack/react-query-next-experimental': - specifier: ^5.100.11 - version: 5.100.11 + specifier: ^5.100.13 + version: 5.100.14 '@testcontainers/mysql': specifier: ^12.0.0 version: 12.0.0 @@ -762,22 +762,22 @@ importers: version: 3.44.0(react@19.2.6) '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.11(react@19.2.6) + version: 5.100.14(react@19.2.6) '@tanstack/react-query-devtools': specifier: 'catalog:' - version: 5.100.11(@tanstack/react-query@5.100.11(react@19.2.6))(react@19.2.6) + version: 5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(react@19.2.6) '@tanstack/react-query-next-experimental': specifier: 'catalog:' - version: 5.100.11(@tanstack/react-query@5.100.11(react@19.2.6))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6) + version: 5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6) '@trpc/client': specifier: 'catalog:' version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/next': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3) '@trpc/react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) '@trpc/server': specifier: 'catalog:' version: 11.17.0(typescript@5.9.3) @@ -1123,19 +1123,19 @@ importers: version: 1.4.0 '@tanstack/react-query': specifier: 'catalog:' - version: 5.100.11(react@19.2.6) + version: 5.100.14(react@19.2.6) '@trpc/client': specifier: 'catalog:' version: 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) '@trpc/server': specifier: 'catalog:' version: 11.17.0(typescript@5.9.3) '@trpc/tanstack-react-query': specifier: 'catalog:' - version: 11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + version: 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) lodash.clonedeep: specifier: 'catalog:' version: 4.5.0 @@ -4878,27 +4878,27 @@ packages: resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} engines: {node: '>=12'} - '@tanstack/query-core@5.100.11': - resolution: {integrity: sha512-lmE0994apShXPj8CUxgx4ch5yUJhE9k/+tVwihBvPOyerACWdBocfFg24t8+0RhtlTd7tEgchDkhlCxNssvDxw==} + '@tanstack/query-core@5.100.14': + resolution: {integrity: sha512-5X41dGpxgeaHISCRW2oYwcSycZeULZzAunaudXT9ov1KOTj9xwt0CH6hbwqP1/z74ZWF7rYFnDpyYH07XFcZew==} - '@tanstack/query-devtools@5.100.11': - resolution: {integrity: sha512-47rVBDuGMW/A4ekt3YQdz+q0JSIwktwGnWCYyQUvSs2/g/Oa+6Fi2/IQk4/Y4vf6u1uwI7hOogHslgMC8f3X/Q==} + '@tanstack/query-devtools@5.100.14': + resolution: {integrity: sha512-g96SmSSQecYTYcyuAMRXr895GplJv01UGt7qttQWPOUyZ5EGz5tbRc589bMc2m5BsPFD6O0PCEAHdbDYNP6UBw==} - '@tanstack/react-query-devtools@5.100.11': - resolution: {integrity: sha512-75RFlJEG53Ed/Cxe5WLmgIpOElPNpgLZq7h0fLFnM5XwTYxSTk1rX/gC6MqGVXsSdrbP7zn7hPSJx9MinwiUHA==} + '@tanstack/react-query-devtools@5.100.14': + resolution: {integrity: sha512-JkP5VDgKOw3t/QSA1OABRHEqx8BuNs5MfvZRooNqdvN57SzTuGq3fKR1a2IH5rqa5HDLUm+FOXUEnB9ueHiLzg==} peerDependencies: - '@tanstack/react-query': ^5.100.11 + '@tanstack/react-query': ^5.100.14 react: ^18 || ^19 - '@tanstack/react-query-next-experimental@5.100.11': - resolution: {integrity: sha512-3girQtwjPJMqAlggOpIugr8JG+prVolAetT5ETwnf0tcAG/w3yQ275xAi2hVc2aayuBGXJjwHNlxDYGqwo1whA==} + '@tanstack/react-query-next-experimental@5.100.14': + resolution: {integrity: sha512-/0uuRT7cXRJEifEuH3F5twngMHlznJs9nl62PMBvQJhgs5y7sA4GugElszXTStsgS3/TlkkfjWhSFDlIgEfiAg==} peerDependencies: - '@tanstack/react-query': ^5.100.11 + '@tanstack/react-query': ^5.100.14 next: ^13 || ^14 || ^15 || ^16 react: ^18 || ^19 - '@tanstack/react-query@5.100.11': - resolution: {integrity: sha512-J0f9s5x3LE1450nNNfYx+e/n0DMa0uOBdFJUy5r0RvmsXd4nB/n0rbHtHI1vYXhikNFan+wf51p6Tmp4c8ucrg==} + '@tanstack/react-query@5.100.14': + resolution: {integrity: sha512-oOr6aRdSFEwWhzxEkD/9ZcItM3+LjBSkeVmadWKwUssAHTsqd/7bOjWrX4AbvEkoEhgAxzN0Xk6H/aYzXiYBAw==} peerDependencies: react: ^18 || ^19 @@ -12159,25 +12159,25 @@ snapshots: dependencies: remove-accents: 0.5.0 - '@tanstack/query-core@5.100.11': {} + '@tanstack/query-core@5.100.14': {} - '@tanstack/query-devtools@5.100.11': {} + '@tanstack/query-devtools@5.100.14': {} - '@tanstack/react-query-devtools@5.100.11(@tanstack/react-query@5.100.11(react@19.2.6))(react@19.2.6)': + '@tanstack/react-query-devtools@5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(react@19.2.6)': dependencies: - '@tanstack/query-devtools': 5.100.11 - '@tanstack/react-query': 5.100.11(react@19.2.6) + '@tanstack/query-devtools': 5.100.14 + '@tanstack/react-query': 5.100.14(react@19.2.6) react: 19.2.6 - '@tanstack/react-query-next-experimental@5.100.11(@tanstack/react-query@5.100.11(react@19.2.6))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6)': + '@tanstack/react-query-next-experimental@5.100.14(@tanstack/react-query@5.100.14(react@19.2.6))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react@19.2.6)': dependencies: - '@tanstack/react-query': 5.100.11(react@19.2.6) + '@tanstack/react-query': 5.100.14(react@19.2.6) next: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0) react: 19.2.6 - '@tanstack/react-query@5.100.11(react@19.2.6)': + '@tanstack/react-query@5.100.14(react@19.2.6)': dependencies: - '@tanstack/query-core': 5.100.11 + '@tanstack/query-core': 5.100.14 react: 19.2.6 '@tanstack/react-table@8.20.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': @@ -12450,7 +12450,7 @@ snapshots: '@trpc/server': 11.17.0(typescript@5.9.3) typescript: 5.9.3 - '@trpc/next@11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3)': + '@trpc/next@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(next@16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3)': dependencies: '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/server': 11.17.0(typescript@5.9.3) @@ -12459,12 +12459,12 @@ snapshots: react-dom: 19.2.6(react@19.2.6) typescript: 5.9.3 optionalDependencies: - '@tanstack/react-query': 5.100.11(react@19.2.6) - '@trpc/react-query': 11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) + '@tanstack/react-query': 5.100.14(react@19.2.6) + '@trpc/react-query': 11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3) - '@trpc/react-query@11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': + '@trpc/react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': dependencies: - '@tanstack/react-query': 5.100.11(react@19.2.6) + '@tanstack/react-query': 5.100.14(react@19.2.6) '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/server': 11.17.0(typescript@5.9.3) react: 19.2.6 @@ -12474,9 +12474,9 @@ snapshots: dependencies: typescript: 5.9.3 - '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.11(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': + '@trpc/tanstack-react-query@11.17.0(@tanstack/react-query@5.100.14(react@19.2.6))(@trpc/client@11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3))(@trpc/server@11.17.0(typescript@5.9.3))(react@19.2.6)(typescript@5.9.3)': dependencies: - '@tanstack/react-query': 5.100.11(react@19.2.6) + '@tanstack/react-query': 5.100.14(react@19.2.6) '@trpc/client': 11.17.0(@trpc/server@11.17.0(typescript@5.9.3))(typescript@5.9.3) '@trpc/server': 11.17.0(typescript@5.9.3) react: 19.2.6 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0a6bdcd8d..c597acaea 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -43,9 +43,9 @@ catalog: "@semantic-release/release-notes-generator": ^14.1.1 "@t3-oss/env-nextjs": ^0.13.11 "@tabler/icons-react": ^3.44.0 - "@tanstack/react-query": ^5.100.11 - "@tanstack/react-query-devtools": ^5.100.11 - "@tanstack/react-query-next-experimental": ^5.100.11 + "@tanstack/react-query": ^5.100.13 + "@tanstack/react-query-devtools": ^5.100.13 + "@tanstack/react-query-next-experimental": ^5.100.13 "@testcontainers/mysql": ^12.0.0 "@testcontainers/postgresql": ^12.0.0 "@testcontainers/redis": ^12.0.0 From 9a538941eedc17d4b3e55666298b96c6c8230cd6 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Wed, 27 May 2026 23:20:59 +0000 Subject: [PATCH 3/8] chore(deps): update dependency ws to ^8.21.0 (#5804) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 20 +++++++++++++++++--- pnpm-workspace.yaml | 2 +- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce2c1c188..e88bc9b48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -508,8 +508,8 @@ catalogs: specifier: 3.19.0 version: 3.19.0 ws: - specifier: ^8.20.1 - version: 8.20.1 + specifier: ^8.21.0 + version: 8.21.0 xml2js: specifier: ^0.6.2 version: 0.6.2 @@ -1013,7 +1013,7 @@ importers: version: 4.20.4 ws: specifier: 'catalog:' - version: 8.20.1 + version: 8.21.0 devDependencies: '@homarr/tsconfig': specifier: workspace:^0.1.0 @@ -9743,6 +9743,18 @@ packages: utf-8-validate: optional: true + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xcase@2.0.1: resolution: {integrity: sha512-UmFXIPU+9Eg3E9m/728Bii0lAIuoc+6nbrNUKaRPJOFp91ih44qqGlWtxMB6kXFrRD6po+86ksHM5XHCfk6iPw==} @@ -17367,6 +17379,8 @@ snapshots: ws@8.20.1: {} + ws@8.21.0: {} + xcase@2.0.1: {} xml-but-prettier@1.0.1: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c597acaea..0d420f648 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -171,7 +171,7 @@ catalog: vite-tsconfig-paths: ^6.1.1 vitest: ^4.1.7 winston: 3.19.0 - ws: ^8.20.1 + ws: ^8.21.0 xml2js: ^0.6.2 yaml: 2.9.0 zod: ^4.4.3 From a0cc68798d1cc89d3148874614fdbd6baafd9fec Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 03:50:55 +0000 Subject: [PATCH 4/8] chore(deps): update mantine monorepo to ^9.2.1 (#5801) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- pnpm-lock.yaml | 32 +++++++++++++------------------- pnpm-workspace.yaml | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 30 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e88bc9b48..d09d3fd6c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,37 +58,37 @@ catalogs: specifier: ^1.4.0 version: 1.4.0 '@mantine/charts': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/colors-generator': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/core': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/dates': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/dropzone': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/form': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/hooks': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/modals': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/notifications': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/spotlight': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@mantine/tiptap': - specifier: ^9.2.0 + specifier: ^9.2.1 version: 9.2.1 '@octokit/auth-app': specifier: ^8.2.0 @@ -3288,9 +3288,6 @@ packages: react: '>=17.0.0' react-dom: '>=17.0.0' - '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - '@floating-ui/utils@0.2.11': resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} @@ -10459,7 +10456,7 @@ snapshots: '@floating-ui/core@1.7.3': dependencies: - '@floating-ui/utils': 0.2.10 + '@floating-ui/utils': 0.2.11 optional: true '@floating-ui/core@1.7.5': @@ -10469,7 +10466,7 @@ snapshots: '@floating-ui/dom@1.7.4': dependencies: '@floating-ui/core': 1.7.3 - '@floating-ui/utils': 0.2.10 + '@floating-ui/utils': 0.2.11 optional: true '@floating-ui/dom@1.7.6': @@ -10491,9 +10488,6 @@ snapshots: react-dom: 19.2.6(react@19.2.6) tabbable: 6.2.0 - '@floating-ui/utils@0.2.10': - optional: true - '@floating-ui/utils@0.2.11': {} '@formatjs/ecma402-abstract@3.1.0': diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0d420f648..46244a138 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -20,17 +20,17 @@ catalog: "@immich/sdk": ^2.7.5 "@jellyfin/sdk": ^0.13.0 "@kubernetes/client-node": ^1.4.0 - "@mantine/charts": ^9.2.0 - "@mantine/colors-generator": ^9.2.0 - "@mantine/core": ^9.2.0 - "@mantine/dates": ^9.2.0 - "@mantine/dropzone": ^9.2.0 - "@mantine/form": ^9.2.0 - "@mantine/hooks": ^9.2.0 - "@mantine/modals": ^9.2.0 - "@mantine/notifications": ^9.2.0 - "@mantine/spotlight": ^9.2.0 - "@mantine/tiptap": ^9.2.0 + "@mantine/charts": ^9.2.1 + "@mantine/colors-generator": ^9.2.1 + "@mantine/core": ^9.2.1 + "@mantine/dates": ^9.2.1 + "@mantine/dropzone": ^9.2.1 + "@mantine/form": ^9.2.1 + "@mantine/hooks": ^9.2.1 + "@mantine/modals": ^9.2.1 + "@mantine/notifications": ^9.2.1 + "@mantine/spotlight": ^9.2.1 + "@mantine/tiptap": ^9.2.1 "@next/eslint-plugin-next": 16.2.6 "@octokit/auth-app": ^8.2.0 "@paralleldrive/cuid2": ^3.3.0 From b19549b601636bcbc2fadaa270a77a9fdb48b77a Mon Sep 17 00:00:00 2001 From: Vivaan Dhawan <150339722+VIVAAN-DHAWAN@users.noreply.github.com> Date: Thu, 28 May 2026 13:18:00 +0530 Subject: [PATCH 5/8] fix: parse Speedtest Tracker created_at as local time (#5751) --- .../speedtest-tracker-types.ts | 2 +- .../test/speedtest-tracker-types.spec.ts | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 packages/integrations/src/speedtest-tracker/test/speedtest-tracker-types.spec.ts diff --git a/packages/integrations/src/speedtest-tracker/speedtest-tracker-types.ts b/packages/integrations/src/speedtest-tracker/speedtest-tracker-types.ts index 83aa5bb24..e7c5b7a44 100644 --- a/packages/integrations/src/speedtest-tracker/speedtest-tracker-types.ts +++ b/packages/integrations/src/speedtest-tracker/speedtest-tracker-types.ts @@ -2,7 +2,7 @@ import { z } from "zod/v4"; const createEnvelopeSchema = (dataSchema: T) => z.object({ data: dataSchema }); -const parseTimestamp = (timestamp: string): Date => new Date(`${timestamp.replace(" ", "T")}Z`); +const parseTimestamp = (timestamp: string): Date => new Date(timestamp.replace(" ", "T")); export const speedtestTrackerResultSchema = z.object({ id: z.number().int(), diff --git a/packages/integrations/src/speedtest-tracker/test/speedtest-tracker-types.spec.ts b/packages/integrations/src/speedtest-tracker/test/speedtest-tracker-types.spec.ts new file mode 100644 index 000000000..e5ddafc58 --- /dev/null +++ b/packages/integrations/src/speedtest-tracker/test/speedtest-tracker-types.spec.ts @@ -0,0 +1,19 @@ +import { describe, expect, test } from "vitest"; + +import { speedtestTrackerResultSchema } from "../speedtest-tracker-types"; + +describe("speedtestTrackerResultSchema", () => { + test("parses created_at as Speedtest Tracker local wall time", () => { + const result = speedtestTrackerResultSchema.parse({ + id: 1, + ping: 12, + download_bits: 100, + upload_bits: 50, + healthy: true, + created_at: "2026-05-18 18:30:01", + }); + + expect(result.created_at.getHours()).toBe(18); + expect(result.created_at.getMinutes()).toBe(30); + }); +}); From 4f2b3cf3eeeb3fbca54734ca68d5662f0b44da36 Mon Sep 17 00:00:00 2001 From: "homarr-renovate[bot]" <158783068+homarr-renovate[bot]@users.noreply.github.com> Date: Thu, 28 May 2026 08:09:15 +0000 Subject: [PATCH 6/8] chore(deps): update node.js to v24.16.0 (#5790) Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com> --- .github/workflows/deployment-docker-image.yml | 2 +- .nvmrc | 2 +- Dockerfile | 2 +- deployments/prebuilt-debian/Dockerfile | 2 +- deployments/prebuilt-debian/package.json | 2 +- package.json | 2 +- tooling/github/setup/action.yml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/deployment-docker-image.yml b/.github/workflows/deployment-docker-image.yml index c43094223..98f9357db 100644 --- a/.github/workflows/deployment-docker-image.yml +++ b/.github/workflows/deployment-docker-image.yml @@ -66,7 +66,7 @@ jobs: - uses: actions/setup-node@v6 if: env.SKIP_RELEASE == 'false' with: - node-version: 24.15.0 + node-version: 24.16.0 package-manager-cache: false - run: npm i -g pnpm if: env.SKIP_RELEASE == 'false' diff --git a/.nvmrc b/.nvmrc index 5bf4400f2..b832e4001 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.15.0 +24.16.0 diff --git a/Dockerfile b/Dockerfile index 51b562f7d..fd852fd9e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:24.15.0-alpine AS base +FROM node:24.16.0-alpine AS base FROM base AS builder RUN apk add --no-cache libc6-compat diff --git a/deployments/prebuilt-debian/Dockerfile b/deployments/prebuilt-debian/Dockerfile index 8ac61693e..b51e1d9c4 100644 --- a/deployments/prebuilt-debian/Dockerfile +++ b/deployments/prebuilt-debian/Dockerfile @@ -1,4 +1,4 @@ -FROM node:24.15.0-trixie AS base +FROM node:24.16.0-trixie AS base WORKDIR /app COPY package.json . COPY pnpm-lock.yaml . diff --git a/deployments/prebuilt-debian/package.json b/deployments/prebuilt-debian/package.json index 2e5dd60cf..ed451a14e 100644 --- a/deployments/prebuilt-debian/package.json +++ b/deployments/prebuilt-debian/package.json @@ -5,7 +5,7 @@ "better-sqlite3": "^12.10.0" }, "engines": { - "node": ">=24.15.0", + "node": ">=24.16.0", "pnpm": ">=10.33.4" }, "packageManager": "pnpm@10.33.4", diff --git a/package.json b/package.json index 17862437f..1db82cbe1 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "vitest": "catalog:" }, "engines": { - "node": ">=24.15.0", + "node": ">=24.16.0", "pnpm": ">=10.33.4" }, "packageManager": "pnpm@10.33.4", diff --git a/tooling/github/setup/action.yml b/tooling/github/setup/action.yml index b8374d497..b426ed746 100644 --- a/tooling/github/setup/action.yml +++ b/tooling/github/setup/action.yml @@ -7,7 +7,7 @@ runs: - uses: pnpm/action-setup@v6 - uses: actions/setup-node@v6 with: - node-version: 24.15.0 + node-version: 24.16.0 cache: "pnpm" - shell: bash From c252b4f9accc4523f222354c73f687714640701f Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 28 May 2026 10:56:46 +0200 Subject: [PATCH 7/8] feat(manage): unified management page layout (#5758) --- .../src/app/[locale]/manage/apps/page.tsx | 56 +++++++++--------- .../_components/create-board-button.tsx | 49 +++++++--------- .../src/app/[locale]/manage/boards/page.tsx | 36 +++++++----- .../app/[locale]/manage/integrations/page.tsx | 58 +++++++------------ .../src/app/[locale]/manage/medias/page.tsx | 55 +++++++++--------- .../[locale]/manage/search-engines/page.tsx | 56 +++++++++--------- .../manage/users/_components/user-list.tsx | 21 ++----- .../[locale]/manage/users/groups/_client.tsx | 29 ++++------ .../app/[locale]/manage/users/groups/page.tsx | 14 ++--- .../_components/invite-create-button.tsx | 20 +++++++ .../users/invites/_components/invite-list.tsx | 23 +------- .../[locale]/manage/users/invites/page.tsx | 20 +++++-- .../src/app/[locale]/manage/users/page.tsx | 22 +++++-- .../manage/manage-mobile-primary-action.tsx | 15 +++++ .../components/manage/manage-page-layout.tsx | 44 ++++++++++++++ .../manage/manage-page.constants.ts | 5 ++ .../components/manage/mobile-affix-button.tsx | 6 +- apps/nextjs/src/components/no-results.tsx | 2 +- packages/translation/src/lang/en.json | 6 ++ 19 files changed, 293 insertions(+), 244 deletions(-) create mode 100644 apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-create-button.tsx create mode 100644 apps/nextjs/src/components/manage/manage-mobile-primary-action.tsx create mode 100644 apps/nextjs/src/components/manage/manage-page-layout.tsx create mode 100644 apps/nextjs/src/components/manage/manage-page.constants.ts diff --git a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx index 27ab01fb5..25fa5ac9e 100644 --- a/apps/nextjs/src/app/[locale]/manage/apps/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/apps/page.tsx @@ -1,6 +1,6 @@ import { Fragment } from "react"; import { redirect } from "next/navigation"; -import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text, Title } from "@mantine/core"; +import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text } from "@mantine/core"; import { IconBox, IconPencil } from "@tabler/icons-react"; import { z } from "zod/v4"; @@ -11,9 +11,8 @@ import type { inferSearchParamsFromSchema } from "@homarr/common/types"; import { getI18n, getScopedI18n } from "@homarr/translation/server"; import { Link, SearchInput, TablePagination } from "@homarr/ui"; -import { ManageContainer } from "~/components/manage/manage-container"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; import { MobileAffixButton } from "~/components/manage/mobile-affix-button"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; import { NoResults } from "~/components/no-results"; import { AppDeleteButton } from "./_app-delete-button"; @@ -39,34 +38,31 @@ export default async function AppsPage(props: AppsPageProps) { const { items: apps, totalCount } = await api.app.getPaginated(searchParams); const t = await getScopedI18n("app"); - return ( - - - - {t("page.list.title")} - - - {session.user.permissions.includes("app-create") && ( - - {t("page.create.title")} - - )} - - {apps.length === 0 && } - {apps.length > 0 && ( - - {apps.map((app) => ( - - ))} - - )} + const canCreate = session.user.permissions.includes("app-create"); - {/* Added margin to not hide pagination behind affix-button */} - - - - - + return ( + + {t("page.create.title")} + + ) : undefined + } + toolbar={} + footer={} + floatingPrimaryAction={canCreate} + > + {apps.length === 0 && } + {apps.length > 0 && ( + + {apps.map((app) => ( + + ))} + + )} + ); } diff --git a/apps/nextjs/src/app/[locale]/manage/boards/_components/create-board-button.tsx b/apps/nextjs/src/app/[locale]/manage/boards/_components/create-board-button.tsx index 849db72e7..5e9642e32 100644 --- a/apps/nextjs/src/app/[locale]/manage/boards/_components/create-board-button.tsx +++ b/apps/nextjs/src/app/[locale]/manage/boards/_components/create-board-button.tsx @@ -1,43 +1,38 @@ "use client"; -import { Affix, Button, Menu } from "@mantine/core"; +import { Button, Menu } from "@mantine/core"; import { IconCategoryPlus, IconChevronDown, IconFileImport } from "@tabler/icons-react"; import { useModalAction } from "@homarr/modals"; import { AddBoardModal, ImportBoardModal } from "@homarr/modals-collection"; import { useI18n } from "@homarr/translation/client"; +import { ManageMobilePrimaryAction } from "~/components/manage/manage-mobile-primary-action"; + export const CreateBoardButton = () => { const t = useI18n(); const { openModal: openAddModal } = useModalAction(AddBoardModal); const { openModal: openImportModal } = useModalAction(ImportBoardModal); - const buttonGroupContent = ( - <> - - - - - - - }> - {t("board.action.oldImport.label")} - - - - - ); - return ( - <> - {buttonGroupContent} - - {buttonGroupContent} - - + + + + + + + + + }> + {t("board.action.oldImport.label")} + + + + + ); }; diff --git a/apps/nextjs/src/app/[locale]/manage/boards/page.tsx b/apps/nextjs/src/app/[locale]/manage/boards/page.tsx index 9c0a28344..796c6e5c0 100644 --- a/apps/nextjs/src/app/[locale]/manage/boards/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/boards/page.tsx @@ -9,12 +9,17 @@ import { Group, Menu, MenuTarget, - Stack, Text, - Title, Tooltip, } from "@mantine/core"; -import { IconDeviceMobile, IconDotsVertical, IconHomeFilled, IconLock, IconWorld } from "@tabler/icons-react"; +import { + IconDeviceMobile, + IconDotsVertical, + IconHomeFilled, + IconLayoutDashboard, + IconLock, + IconWorld, +} from "@tabler/icons-react"; import type { RouterOutputs } from "@homarr/api"; import { api } from "@homarr/api/server"; @@ -23,8 +28,8 @@ import { getScopedI18n } from "@homarr/translation/server"; import { Link, UserAvatar } from "@homarr/ui"; import { getBoardPermissionsAsync } from "~/components/board/permissions/server"; -import { ManageContainer } from "~/components/manage/manage-container"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; +import { NoResults } from "~/components/no-results"; import { BoardCardMenuDropdown } from "./_components/board-card-menu-dropdown"; import { CreateBoardButton } from "./_components/create-board-button"; @@ -35,23 +40,22 @@ export default async function ManageBoardsPage() { const canCreateBoards = session?.user.permissions.includes("board-create"); return ( - - - - - {t("title")} - {canCreateBoards && } - - - + : undefined} + floatingPrimaryAction={canCreateBoards} + > + {boards.length === 0 && } + {boards.length > 0 && ( + {boards.map((board) => ( ))} - - + )} + ); } diff --git a/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx b/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx index 1fe3a83e2..994d63b3c 100644 --- a/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/integrations/page.tsx @@ -7,9 +7,7 @@ import { AccordionPanel, ActionIcon, ActionIconGroup, - Affix, Anchor, - Box, Button, Divider, Group, @@ -24,9 +22,8 @@ import { TableThead, TableTr, Text, - Title, } from "@mantine/core"; -import { IconChevronDown, IconChevronUp, IconPencil, IconPlugX } from "@tabler/icons-react"; +import { IconChevronDown, IconPencil, IconPlugX } from "@tabler/icons-react"; import type { RouterOutputs } from "@homarr/api"; import { api } from "@homarr/api/server"; @@ -37,8 +34,8 @@ import { getIntegrationName } from "@homarr/definitions"; import { getScopedI18n } from "@homarr/translation/server"; import { CountBadge, IntegrationAvatar, Link } from "@homarr/ui"; -import { ManageContainer } from "~/components/manage/manage-container"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; +import { ManageMobilePrimaryAction } from "~/components/manage/manage-mobile-primary-action"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; import { NoResults } from "~/components/no-results"; import { env } from "~/env"; import { ActiveTabAccordion } from "../../../../components/active-tab-accordion"; @@ -66,38 +63,23 @@ export default async function IntegrationsPage(props: IntegrationsPageProps) { const canCreateIntegrations = session.user.permissions.includes("integration-create"); return ( - - - - - {t("page.list.title")} - - {canCreateIntegrations && ( - <> - - - - - - - - - - - - - - - - - - - )} - - - - - + + + + + + + + ) : undefined + } + floatingPrimaryAction={canCreateIntegrations} + > + + ); } diff --git a/apps/nextjs/src/app/[locale]/manage/medias/page.tsx b/apps/nextjs/src/app/[locale]/manage/medias/page.tsx index b14ceb531..51d4a2caf 100644 --- a/apps/nextjs/src/app/[locale]/manage/medias/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/medias/page.tsx @@ -4,17 +4,15 @@ import { Anchor, Group, Image, - Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, - Title, Tooltip, } from "@mantine/core"; -import { IconExternalLink } from "@tabler/icons-react"; +import { IconExternalLink, IconPhoto } from "@tabler/icons-react"; import { z } from "zod/v4"; import type { RouterOutputs } from "@homarr/api"; @@ -26,8 +24,9 @@ import { createLocalImageUrl } from "@homarr/icons/local"; import { getI18n } from "@homarr/translation/server"; import { Link, SearchInput, TablePagination, UserAvatar } from "@homarr/ui"; -import { ManageContainer } from "~/components/manage/manage-container"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; +import { ManageMobilePrimaryAction } from "~/components/manage/manage-mobile-primary-action"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; +import { NoResults } from "~/components/no-results"; import { CopyMedia } from "./_actions/copy-media"; import { DeleteMedia } from "./_actions/delete-media"; import { IncludeFromAllUsersSwitch } from "./_actions/show-all"; @@ -48,7 +47,7 @@ interface MediaListPageProps { searchParams: Promise>; } -export default async function GroupsListPage(props: MediaListPageProps) { +export default async function MediaListPage(props: MediaListPageProps) { const session = await auth(); if (!session) { @@ -58,22 +57,31 @@ export default async function GroupsListPage(props: MediaListPageProps) { const t = await getI18n(); const searchParams = searchParamsSchema.parse(await props.searchParams); const { items: medias, totalCount } = await api.media.getPaginated(searchParams); + const canUpload = session.user.permissions.includes("media-upload"); return ( - - - - {t("media.plural")} - - - - {session.user.permissions.includes("media-view-all") && ( - - )} - - - {session.user.permissions.includes("media-upload") && } + + + + ) : undefined + } + toolbar={ + + + {session.user.permissions.includes("media-view-all") && ( + + )} + } + footer={} + floatingPrimaryAction={canUpload} + > + {medias.length === 0 && } + {medias.length > 0 && ( @@ -90,13 +98,8 @@ export default async function GroupsListPage(props: MediaListPageProps) { ))}
- - {/* Added margin to not hide pagination behind affix-button */} - - - -
-
+ )} + ); } diff --git a/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx b/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx index ce2500d02..00ca08055 100644 --- a/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/search-engines/page.tsx @@ -1,5 +1,5 @@ import { redirect } from "next/navigation"; -import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text, Title } from "@mantine/core"; +import { ActionIcon, ActionIconGroup, Anchor, Avatar, Card, Group, Stack, Text } from "@mantine/core"; import { IconPencil, IconSearch } from "@tabler/icons-react"; import { z } from "zod/v4"; @@ -10,9 +10,8 @@ import type { inferSearchParamsFromSchema } from "@homarr/common/types"; import { getI18n, getScopedI18n } from "@homarr/translation/server"; import { Link, SearchInput, TablePagination } from "@homarr/ui"; -import { ManageContainer } from "~/components/manage/manage-container"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; import { MobileAffixButton } from "~/components/manage/mobile-affix-button"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; import { NoResults } from "~/components/no-results"; import { SearchEngineDeleteButton } from "./_search-engine-delete-button"; @@ -38,34 +37,31 @@ export default async function SearchEnginesPage(props: SearchEnginesPageProps) { const tEngine = await getScopedI18n("search.engine"); - return ( - - - - {tEngine("page.list.title")} - - - {session.user.permissions.includes("search-engine-create") && ( - - {tEngine("page.create.title")} - - )} - - {searchEngines.length === 0 && } - {searchEngines.length > 0 && ( - - {searchEngines.map((searchEngine) => ( - - ))} - - )} + const canCreate = session.user.permissions.includes("search-engine-create"); - {/* Added margin to not hide pagination behind affix-button */} - - - - - + return ( + + {tEngine("page.create.title")} + + ) : undefined + } + toolbar={} + footer={} + floatingPrimaryAction={canCreate} + > + {searchEngines.length === 0 && } + {searchEngines.length > 0 && ( + + {searchEngines.map((searchEngine) => ( + + ))} + + )} + ); } diff --git a/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx b/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx index 22f4d1b88..0e0fce5b9 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/_components/user-list.tsx @@ -1,24 +1,22 @@ "use client"; import { useMemo } from "react"; -import { Anchor, Button, Group, Text, Title, Tooltip } from "@mantine/core"; +import { Anchor, Group, Text, Tooltip } from "@mantine/core"; import { IconCheck } from "@tabler/icons-react"; 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 { useI18n, useScopedI18n } from "@homarr/translation/client"; +import { useI18n } from "@homarr/translation/client"; import { Link, UserAvatar } from "@homarr/ui"; import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; interface UserListComponentProps { initialUserList: RouterOutputs["user"]["getAll"]; - credentialsProviderEnabled: boolean; } -export const UserListComponent = ({ initialUserList, credentialsProviderEnabled }: UserListComponentProps) => { - const tUserList = useScopedI18n("management.page.user.list"); +export const UserListComponent = ({ initialUserList }: UserListComponentProps) => { const t = useI18n(); const { data, isLoading } = clientApi.user.getAll.useQuery(undefined, { initialData: initialUserList, @@ -69,21 +67,10 @@ export const UserListComponent = ({ initialUserList, credentialsProviderEnabled enableFullScreenToggle: false, layoutMode: "grid-no-grow", getRowId: (row) => row.id, - renderTopToolbarCustomActions: () => - credentialsProviderEnabled ? ( - - ) : null, state: { isLoading, }, }); - return ( - <> - {tUserList("title")} - - - ); + return ; }; diff --git a/apps/nextjs/src/app/[locale]/manage/users/groups/_client.tsx b/apps/nextjs/src/app/[locale]/manage/users/groups/_client.tsx index 7ca382bff..353bc06ea 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/groups/_client.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/groups/_client.tsx @@ -1,7 +1,7 @@ "use client"; -import { useCallback, useMemo, useState } from "react"; -import { Group, TextInput } from "@mantine/core"; +import { useMemo, useState } from "react"; +import { TextInput } from "@mantine/core"; import { IconSearch } from "@tabler/icons-react"; import type { RouterOutputs } from "@homarr/api"; @@ -33,29 +33,20 @@ export const GroupsList = ({ groups }: GroupsListProps) => { return ( <> - - } - value={search} - onChange={(event) => setSearch(event.currentTarget.value)} - placeholder={`${t("group.search")}...`} - style={{ flex: 1 }} - /> - - - + } + value={search} + onChange={(event) => setSearch(event.currentTarget.value)} + placeholder={`${t("group.search")}...`} + /> ); }; -const AddGroup = () => { +export const AddGroupButton = () => { const t = useI18n(); const { openModal } = useModalAction(AddGroupModal); - const handleAddGroup = useCallback(() => { - openModal(); - }, [openModal]); - - return {t("group.action.create.label")}; + return openModal()}>{t("group.action.create.label")}; }; diff --git a/apps/nextjs/src/app/[locale]/manage/users/groups/page.tsx b/apps/nextjs/src/app/[locale]/manage/users/groups/page.tsx index 19ec73ff7..48f6c8f8f 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/groups/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/groups/page.tsx @@ -1,5 +1,5 @@ import { notFound } from "next/navigation"; -import { Card, Group, Stack, Text, ThemeIcon, Title, UnstyledButton } from "@mantine/core"; +import { Card, Group, Stack, Text, ThemeIcon, UnstyledButton } from "@mantine/core"; import { IconChevronRight, IconUsersGroup } from "@tabler/icons-react"; import { api } from "@homarr/api/server"; @@ -8,9 +8,8 @@ import { everyoneGroup } from "@homarr/definitions"; import { getI18n } from "@homarr/translation/server"; import { Link } from "@homarr/ui"; -import { ManageContainer } from "~/components/manage/manage-container"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; -import { GroupsList } from "./_client"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; +import { AddGroupButton, GroupsList } from "./_client"; import classes from "./groups.module.css"; export default async function GroupsListPage() { @@ -26,11 +25,8 @@ export default async function GroupsListPage() { const groupsWithoutEveryone = groups.filter((group) => group.name !== everyoneGroup); return ( - - + } floatingPrimaryAction> - {t("group.title")} - {dbEveryoneGroup && ( @@ -53,6 +49,6 @@ export default async function GroupsListPage() { - + ); } diff --git a/apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-create-button.tsx b/apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-create-button.tsx new file mode 100644 index 000000000..01c3f40b2 --- /dev/null +++ b/apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-create-button.tsx @@ -0,0 +1,20 @@ +"use client"; + +import { Button } from "@mantine/core"; + +import { useModalAction } from "@homarr/modals"; +import { InviteCreateModal } from "@homarr/modals-collection"; +import { useScopedI18n } from "@homarr/translation/client"; + +import { MANAGE_ACTION_BUTTON_MIN_WIDTH } from "~/components/manage/manage-page.constants"; + +export const InviteCreateButton = () => { + const t = useScopedI18n("management.page.user.invite"); + const { openModal } = useModalAction(InviteCreateModal); + + return ( + + ); +}; diff --git a/apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-list.tsx b/apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-list.tsx index 5fa1b5eff..4bc1eaff1 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-list.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/invites/_components/invite-list.tsx @@ -1,7 +1,7 @@ "use client"; import { useCallback, useMemo } from "react"; -import { ActionIcon, Button, Title } from "@mantine/core"; +import { ActionIcon } from "@mantine/core"; import { IconTrash } from "@tabler/icons-react"; import dayjs from "dayjs"; import relativeTime from "dayjs/plugin/relativeTime"; @@ -10,8 +10,7 @@ import { MantineReactTable } from "mantine-react-table"; import type { RouterOutputs } from "@homarr/api"; import { clientApi } from "@homarr/api/client"; -import { useConfirmModal, useModalAction } from "@homarr/modals"; -import { InviteCreateModal } from "@homarr/modals-collection"; +import { useConfirmModal } from "@homarr/modals"; import { useScopedI18n } from "@homarr/translation/client"; import { useTranslatedMantineReactTable } from "@homarr/ui/hooks"; @@ -65,7 +64,6 @@ export const InviteListComponent = ({ initialInvites }: InviteListComponentProps enableFullScreenToggle: false, layoutMode: "grid-no-grow", getRowId: (row) => row.id, - renderTopToolbarCustomActions: RenderTopToolbarCustomActions, state: { isLoading, }, @@ -74,22 +72,7 @@ export const InviteListComponent = ({ initialInvites }: InviteListComponentProps }, }); - return ( - <> - {t("title")} - - - ); -}; - -const RenderTopToolbarCustomActions = () => { - const t = useScopedI18n("management.page.user.invite"); - const { openModal } = useModalAction(InviteCreateModal); - const handleNewInvite = useCallback(() => { - openModal(); - }, [openModal]); - - return ; + return ; }; const RenderRowActions = ({ row }: { row: MRT_Row }) => { diff --git a/apps/nextjs/src/app/[locale]/manage/users/invites/page.tsx b/apps/nextjs/src/app/[locale]/manage/users/invites/page.tsx index f392e8282..cb5c0423c 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/invites/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/invites/page.tsx @@ -3,8 +3,11 @@ import { notFound } from "next/navigation"; import { api } from "@homarr/api/server"; import { auth } from "@homarr/auth/next"; import { isProviderEnabled } from "@homarr/auth/server"; +import { getScopedI18n } from "@homarr/translation/server"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; +import { ManageMobilePrimaryAction } from "~/components/manage/manage-mobile-primary-action"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; +import { InviteCreateButton } from "./_components/invite-create-button"; import { InviteListComponent } from "./_components/invite-list"; export default async function InvitesOverviewPage() { @@ -17,11 +20,20 @@ export default async function InvitesOverviewPage() { return notFound(); } + const t = await getScopedI18n("management.page.user.invite"); const initialInvites = await api.invite.getAll(); + return ( - <> - + + + + } + floatingPrimaryAction + > - + ); } diff --git a/apps/nextjs/src/app/[locale]/manage/users/page.tsx b/apps/nextjs/src/app/[locale]/manage/users/page.tsx index 94ae5c103..4059b9972 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/page.tsx @@ -4,8 +4,10 @@ import { api } from "@homarr/api/server"; import { auth } from "@homarr/auth/next"; import { isProviderEnabled } from "@homarr/auth/server"; import { getScopedI18n } from "@homarr/translation/server"; +import { Link } from "@homarr/ui"; -import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; +import { ManagePageLayout } from "~/components/manage/manage-page-layout"; +import { MobileAffixButton } from "~/components/manage/mobile-affix-button"; import { createMetaTitle } from "~/metadata"; import { UserListComponent } from "./_components/user-list"; @@ -27,13 +29,23 @@ export default async function UsersPage() { return notFound(); } + const t = await getScopedI18n("management.page.user"); const userList = await api.user.getAll(); const credentialsProviderEnabled = isProviderEnabled("credentials"); return ( - <> - - - + + {t("create.title")} + + ) : undefined + } + floatingPrimaryAction={credentialsProviderEnabled} + > + + ); } diff --git a/apps/nextjs/src/components/manage/manage-mobile-primary-action.tsx b/apps/nextjs/src/components/manage/manage-mobile-primary-action.tsx new file mode 100644 index 000000000..40192e0f8 --- /dev/null +++ b/apps/nextjs/src/components/manage/manage-mobile-primary-action.tsx @@ -0,0 +1,15 @@ +import type { PropsWithChildren } from "react"; +import { Affix, Box } from "@mantine/core"; + +import { MANAGE_ACTION_BUTTON_MIN_WIDTH, MANAGE_AFFIX_POSITION } from "./manage-page.constants"; + +export const ManageMobilePrimaryAction = ({ children }: PropsWithChildren) => ( + <> + + {children} + + + {children} + + +); diff --git a/apps/nextjs/src/components/manage/manage-page-layout.tsx b/apps/nextjs/src/components/manage/manage-page-layout.tsx new file mode 100644 index 000000000..d8655c58c --- /dev/null +++ b/apps/nextjs/src/components/manage/manage-page-layout.tsx @@ -0,0 +1,44 @@ +import type { ReactNode } from "react"; +import type { MantineSize } from "@mantine/core"; +import { Group, Stack, Title } from "@mantine/core"; + +import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb"; +import { ManageContainer } from "./manage-container"; +import { MANAGE_FLOATING_ACTION_BOTTOM_OFFSET } from "./manage-page.constants"; + +interface ManagePageLayoutProps { + title: ReactNode; + primaryAction?: ReactNode; + toolbar?: ReactNode; + footer?: ReactNode; + floatingPrimaryAction?: boolean; + size?: MantineSize; + children: ReactNode; +} + +export const ManagePageLayout = ({ + title, + primaryAction, + toolbar, + footer, + floatingPrimaryAction, + size, + children, +}: ManagePageLayoutProps) => { + const titleNode = typeof title === "string" ? {title} : title; + + return ( + + + + + {titleNode} + {primaryAction} + + {toolbar} + {children} + {footer && {footer}} + + + ); +}; diff --git a/apps/nextjs/src/components/manage/manage-page.constants.ts b/apps/nextjs/src/components/manage/manage-page.constants.ts new file mode 100644 index 000000000..7b3a59884 --- /dev/null +++ b/apps/nextjs/src/components/manage/manage-page.constants.ts @@ -0,0 +1,5 @@ +export const MANAGE_AFFIX_POSITION = { bottom: 20, right: 20 } as const; + +export const MANAGE_FLOATING_ACTION_BOTTOM_OFFSET = 48; + +export const MANAGE_ACTION_BUTTON_MIN_WIDTH = 160; diff --git a/apps/nextjs/src/components/manage/mobile-affix-button.tsx b/apps/nextjs/src/components/manage/mobile-affix-button.tsx index abe4f017c..f711751de 100644 --- a/apps/nextjs/src/components/manage/mobile-affix-button.tsx +++ b/apps/nextjs/src/components/manage/mobile-affix-button.tsx @@ -2,13 +2,15 @@ import { forwardRef } from "react"; import type { ButtonProps } from "@mantine/core"; import { Affix, Button, createPolymorphicComponent } from "@mantine/core"; +import { MANAGE_ACTION_BUTTON_MIN_WIDTH, MANAGE_AFFIX_POSITION } from "./manage-page.constants"; + type MobileAffixButtonProps = Omit; export const MobileAffixButton = createPolymorphicComponent<"button", MobileAffixButtonProps>( forwardRef((props, ref) => ( <> - @@ -253,7 +253,6 @@ const ContainerActionBarButton = (props: ContainerActionBarButtonProps) => { onClick={handleClickAsync} loading={isPending} variant="light" - radius="md" > {t(`${props.action}.label`)} diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css index b439e7f4b..dbc035932 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.module.css @@ -4,28 +4,16 @@ 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)); - } + border-left: 1px solid var(--mantine-color-blue-6); + background-color: light-dark( + var(--mantine-color-blue-0), + color-mix(in oklch, var(--mantine-color-blue-9), transparent 85%) + ); @mixin rtl { padding-left: var(--mantine-spacing-xs); padding-right: calc(var(--mantine-spacing-xs) * 2); - - &::before { - left: unset; - right: 0; - } + border-left: none; + border-right: 1px solid var(--mantine-color-blue-6); } } diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx index a8704e1b5..37ed66fe2 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/header-card/header-card.tsx @@ -23,7 +23,6 @@ export function HeaderCard(props: HeaderCardProps) { - + + diff --git a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx index d2405fcf7..17c922c90 100644 --- a/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx +++ b/apps/nextjs/src/app/[locale]/manage/tools/kubernetes/cluster-dashboard/resource-tile/resource-tile.tsx @@ -17,12 +17,7 @@ interface ResourceTileProps { export function ResourceTile(props: ResourceTileProps) { const t = useI18n(); return ( - + {props.label} diff --git a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx index e4ee64583..2137add34 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/[userId]/general/_components/_profile-avatar-form.tsx @@ -95,7 +95,7 @@ export const UserProfileAvatarForm = ({ user }: UserProfileAvatarForm) => { return ( - + diff --git a/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx b/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx index fbaae76c7..f443ae585 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/create/_components/create-user-stepper.tsx @@ -149,7 +149,7 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC color={!generalForm.isValid() ? "red" : undefined} > - + - + - + @@ -198,20 +198,20 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC - + - + {generalForm.values.username} - + {t("step.completed.title")} diff --git a/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx b/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx index 24d003a84..675f3f435 100644 --- a/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx +++ b/apps/nextjs/src/app/[locale]/manage/users/create/_components/stepper-navigation.tsx @@ -25,7 +25,7 @@ export const StepperNavigationComponent = ({ }: StepperNavigationComponentProps) => { const t = useI18n(); return ( - + {!isComplete ? ( @@ -170,7 +170,7 @@ const SupportedIntegrations = ({ integrations, mt }: SupportedIntegrationsProps) return (
- + {integrations.slice(0, countToShow).map((integration) => ( diff --git a/apps/nextjs/src/components/board/sections/category-section.tsx b/apps/nextjs/src/components/board/sections/category-section.tsx index feedcb964..4c3958859 100644 --- a/apps/nextjs/src/components/board/sections/category-section.tsx +++ b/apps/nextjs/src/components/board/sections/category-section.tsx @@ -45,13 +45,7 @@ export const BoardCategorySection = ({ section }: Props) => { }); return ( - + diff --git a/apps/nextjs/src/components/board/sections/category/category-menu.tsx b/apps/nextjs/src/components/board/sections/category/category-menu.tsx index 894db8949..9e3928198 100644 --- a/apps/nextjs/src/components/board/sections/category/category-menu.tsx +++ b/apps/nextjs/src/components/board/sections/category/category-menu.tsx @@ -30,9 +30,9 @@ export const CategoryMenu = ({ category }: Props) => { const t = useScopedI18n("section.category"); return ( - + - + diff --git a/apps/nextjs/src/components/board/sections/dynamic-section.tsx b/apps/nextjs/src/components/board/sections/dynamic-section.tsx index 39818c5de..8bb0a52c3 100644 --- a/apps/nextjs/src/components/board/sections/dynamic-section.tsx +++ b/apps/nextjs/src/components/board/sections/dynamic-section.tsx @@ -28,7 +28,6 @@ export const BoardDynamicSection = ({ section }: Props) => { className={combineClasses(classes.itemCard, section.options.customCssClasses.join(" "))} w="100%" h="100%" - withBorder styles={{ root: { overflow: "visible", diff --git a/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx b/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx index f73328024..cffc3446f 100644 --- a/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx +++ b/apps/nextjs/src/components/board/sections/dynamic/dynamic-menu.tsx @@ -43,9 +43,17 @@ export const BoardDynamicSectionMenu = ({ section }: { section: DynamicSectionIt }; return ( - + - + diff --git a/apps/nextjs/src/components/layout/navigation-link.tsx b/apps/nextjs/src/components/layout/navigation-link.tsx index dd6949682..2d98d42ec 100644 --- a/apps/nextjs/src/components/layout/navigation-link.tsx +++ b/apps/nextjs/src/components/layout/navigation-link.tsx @@ -12,16 +12,7 @@ export const CommonNavLink = (props: ClientNavigationLink) => const NavLinkHref = (props: NavigationLinkHref) => { const pathname = usePathname(); return props.external ? ( - + ) : ( { leftSection={props.icon} href={props.href} active={pathname === props.href} - style={{ - borderRadius: 5, - }} /> ); }; @@ -40,14 +28,7 @@ const NavLinkWithItems = (props: NavigationLinkWithItems) => { const pathname = usePathname(); const isActive = props.items.some((item) => item.href === pathname); return ( - + {props.items.map((item) => ( ))} diff --git a/apps/nextjs/src/components/manage/danger-zone.tsx b/apps/nextjs/src/components/manage/danger-zone.tsx index 30bfb3e37..38f63185b 100644 --- a/apps/nextjs/src/components/manage/danger-zone.tsx +++ b/apps/nextjs/src/components/manage/danger-zone.tsx @@ -15,7 +15,7 @@ export const DangerZoneRoot = async ({ children }: DangerZoneRootProps) => { {t("common.dangerZone")} - + {Array.isArray(children) ? children.map((child, index) => ( diff --git a/apps/nextjs/src/components/no-results.tsx b/apps/nextjs/src/components/no-results.tsx index ecc794e46..9506bafa4 100644 --- a/apps/nextjs/src/components/no-results.tsx +++ b/apps/nextjs/src/components/no-results.tsx @@ -14,7 +14,7 @@ interface NoResultsProps { export const NoResults = ({ icon: Icon, title, action }: NoResultsProps) => { return ( - + diff --git a/apps/nextjs/src/components/user-avatar-menu.tsx b/apps/nextjs/src/components/user-avatar-menu.tsx index 454ecca78..8faa8f6fa 100644 --- a/apps/nextjs/src/components/user-avatar-menu.tsx +++ b/apps/nextjs/src/components/user-avatar-menu.tsx @@ -52,7 +52,7 @@ export const UserAvatarMenu = ({ children, availableUpdatesPromise }: UserAvatar return ( // We use keepMounted so we can add event listeners to prevent navigating away without saving the board - + }> diff --git a/packages/forms-collection/src/icon-picker/icon-picker.tsx b/packages/forms-collection/src/icon-picker/icon-picker.tsx index 0ad036f81..f407196a6 100644 --- a/packages/forms-collection/src/icon-picker/icon-picker.tsx +++ b/packages/forms-collection/src/icon-picker/icon-picker.tsx @@ -108,10 +108,9 @@ export const IconPicker = ({ cursor: "pointer", }} className={classes.iconCard} - withBorder > - + diff --git a/packages/modals-collection/src/apps/app-select-modal.tsx b/packages/modals-collection/src/apps/app-select-modal.tsx index e488eb3a6..e5530d341 100644 --- a/packages/modals-collection/src/apps/app-select-modal.tsx +++ b/packages/modals-collection/src/apps/app-select-modal.tsx @@ -77,7 +77,7 @@ export const AppSelectModal = createModal(({ actions, inner {t("app.action.create.description")} - @@ -100,7 +100,7 @@ export const AppSelectModal = createModal(({ actions, inner {app.description ?? ""} - diff --git a/packages/modals-collection/src/docker/add-docker-app-to-homarr.tsx b/packages/modals-collection/src/docker/add-docker-app-to-homarr.tsx index f94bf8f24..d83b16fdd 100644 --- a/packages/modals-collection/src/docker/add-docker-app-to-homarr.tsx +++ b/packages/modals-collection/src/docker/add-docker-app-to-homarr.tsx @@ -58,7 +58,7 @@ export const AddDockerAppToHomarrModal = createModal( }; return ( - + {innerProps.selectedContainers.map((container, index) => ( diff --git a/packages/modals-collection/src/search-engines/request-media-modal.tsx b/packages/modals-collection/src/search-engines/request-media-modal.tsx index efb92cf7a..89306f3af 100644 --- a/packages/modals-collection/src/search-engines/request-media-modal.tsx +++ b/packages/modals-collection/src/search-engines/request-media-modal.tsx @@ -83,15 +83,10 @@ export const RequestMediaModal = createModal(({ actions, return ( - + {data && ( - poster + poster {data.overview} diff --git a/packages/old-import/src/components/initial/board-selection-card.tsx b/packages/old-import/src/components/initial/board-selection-card.tsx index 294e68885..4665ec2cd 100644 --- a/packages/old-import/src/components/initial/board-selection-card.tsx +++ b/packages/old-import/src/components/initial/board-selection-card.tsx @@ -38,7 +38,7 @@ export const BoardSelectionCard = ({ selections, updateSelections }: BoardSelect } return ( - + @@ -57,7 +57,7 @@ export const BoardSelectionCard = ({ selections, updateSelections }: BoardSelect {[...selections.entries()].map(([name, selected]) => ( - + { const tImportSettings = useScopedI18n("init.step.import.importSettings"); return ( - + {tImportSettings("title")} diff --git a/packages/old-import/src/components/initial/import-summary-card.tsx b/packages/old-import/src/components/initial/import-summary-card.tsx index 876d1f43c..9993b3ac2 100644 --- a/packages/old-import/src/components/initial/import-summary-card.tsx +++ b/packages/old-import/src/components/initial/import-summary-card.tsx @@ -13,7 +13,7 @@ interface ImportSummaryCardProps { export const ImportSummaryCard = ({ counts, onSubmit, loading }: ImportSummaryCardProps) => { const tSummary = useScopedI18n("init.step.import.summary"); return ( - + {tSummary("title")} @@ -24,7 +24,7 @@ export const ImportSummaryCard = ({ counts, onSubmit, loading }: ImportSummaryCa {objectEntries(counts).map(([key, count]) => ( - + {tSummary(`entities.${key}`)} diff --git a/packages/spotlight/src/components/spotlight.tsx b/packages/spotlight/src/components/spotlight.tsx index c90542f45..4ca086f3b 100644 --- a/packages/spotlight/src/components/spotlight.tsx +++ b/packages/spotlight/src/components/spotlight.tsx @@ -110,6 +110,7 @@ const SpotlightWithActiveMode = ({ modeState, queryState, activeMode }: Spotligh inputRef.current?.focus(); }} variant="subtle" + aria-label={t("common.action.close")} > diff --git a/packages/translation/src/lang/en.json b/packages/translation/src/lang/en.json index d7b690137..a62728845 100644 --- a/packages/translation/src/lang/en.json +++ b/packages/translation/src/lang/en.json @@ -1087,7 +1087,9 @@ "checkoutDocs": "Check out the documentation", "checkLogs": "Check logs for more details", "tryAgain": "Try again", - "loading": "Loading" + "loading": "Loading", + "show": "Show", + "hide": "Hide" }, "here": "here", "iconPicker": { @@ -1252,7 +1254,8 @@ "menu": { "label": { "create": "New category", - "changePosition": "Change position" + "changePosition": "Change position", + "settings": "Settings" } }, "openAllInNewTabs": { diff --git a/packages/ui/src/components/user-avatar-group.tsx b/packages/ui/src/components/user-avatar-group.tsx index 1aa2fbf6b..f014987e1 100644 --- a/packages/ui/src/components/user-avatar-group.tsx +++ b/packages/ui/src/components/user-avatar-group.tsx @@ -12,7 +12,7 @@ interface UserAvatarGroupProps { export const UserAvatarGroup = ({ size, limit, users }: UserAvatarGroupProps) => { return ( - + {users.slice(0, limit).map((user) => ( diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 2a4bb91a1..364f7a394 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -2,6 +2,7 @@ import type { MantineProviderProps } from "@mantine/core"; import { theme } from "./theme"; +export { theme } from "./theme"; export * from "./components"; export const uiConfiguration = { diff --git a/packages/ui/src/theme.ts b/packages/ui/src/theme.ts index 7439ae440..9aea93dbf 100644 --- a/packages/ui/src/theme.ts +++ b/packages/ui/src/theme.ts @@ -1,13 +1,103 @@ -import { createTheme } from "@mantine/core"; - -import { primaryColor } from "./theme/colors/primary"; -import { secondaryColor } from "./theme/colors/secondary"; +import { createTheme, rem } from "@mantine/core"; export const theme = createTheme({ - colors: { - primaryColor, - secondaryColor, + primaryColor: "red", + autoContrast: true, + respectReducedMotion: true, + cursorType: "pointer", + + fontFamily: "Inter, system-ui, -apple-system, sans-serif", + fontFamilyMonospace: "ui-monospace, 'Cascadia Code', 'Fira Code', monospace", + + headings: { + fontFamily: "Inter, system-ui, -apple-system, sans-serif", + fontWeight: "600", + sizes: { + h1: { fontSize: rem(36), lineHeight: "1.1", fontWeight: "700" }, + h2: { fontSize: rem(24), lineHeight: "1.2", fontWeight: "700" }, + h3: { fontSize: rem(20), lineHeight: "1.3", fontWeight: "600" }, + h4: { fontSize: rem(16), lineHeight: "1.4", fontWeight: "600" }, + h5: { fontSize: rem(14), lineHeight: "1.5", fontWeight: "600" }, + h6: { fontSize: rem(12), lineHeight: "1.5", fontWeight: "600" }, + }, + }, + + fontSizes: { + xs: rem(12), + sm: rem(14), + md: rem(16), + lg: rem(18), + xl: rem(20), + }, + + spacing: { + xs: rem(10), + sm: rem(12), + md: rem(16), + lg: rem(20), + xl: rem(32), + }, + + radius: { + xs: rem(4), + sm: rem(4), + md: rem(8), + lg: rem(12), + xl: rem(16), + }, + defaultRadius: "md", + + shadows: { + xs: "0 1px 2px rgba(0, 0, 0, 0.04)", + sm: "0 1px 3px rgba(0, 0, 0, 0.06)", + md: "0 2px 8px rgba(0, 0, 0, 0.08)", + lg: "0 4px 12px rgba(0, 0, 0, 0.10)", + xl: "0 8px 24px rgba(0, 0, 0, 0.12)", + }, + + components: { + Card: { + defaultProps: { + withBorder: true, + radius: "lg", + }, + }, + Paper: { + defaultProps: { + withBorder: true, + radius: "md", + }, + }, + Button: { + defaultProps: { + radius: "md", + }, + }, + ActionIcon: { + defaultProps: { + radius: "md", + }, + }, + Tooltip: { + defaultProps: { + openDelay: 300, + }, + }, + Menu: { + defaultProps: { + withArrow: true, + }, + }, + NavLink: { + defaultProps: { + style: { borderRadius: 5 }, + }, + }, + LoadingOverlay: { + defaultProps: { + zIndex: 1000, + overlayProps: { radius: "sm", blur: 2 }, + }, + }, }, - primaryColor: "primaryColor", - defaultRadius: "sm", }); diff --git a/packages/ui/src/theme/colors/primary.ts b/packages/ui/src/theme/colors/primary.ts deleted file mode 100644 index 3bb5ef987..000000000 --- a/packages/ui/src/theme/colors/primary.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { MantineColorsTuple } from "@mantine/core"; - -export const primaryColor: MantineColorsTuple = [ - "#eafbf0", - "#ddefe3", - "#bedcc7", - "#9bc8aa", - "#7eb892", - "#6bad81", - "#60a878", - "#509265", - "#438359", - "#35724a", -]; diff --git a/packages/ui/src/theme/colors/secondary.ts b/packages/ui/src/theme/colors/secondary.ts deleted file mode 100644 index c3a10a691..000000000 --- a/packages/ui/src/theme/colors/secondary.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { MantineColorsTuple } from "@mantine/core"; - -export const secondaryColor: MantineColorsTuple = [ - "#e6f7ff", - "#d9e8f6", - "#b6cde6", - "#90b2d4", - "#6f9ac5", - "#5a8bbd", - "#4d84ba", - "#3d71a4", - "#326595", - "#205885", -]; diff --git a/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx b/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx index d765c1d73..f4f73fd72 100644 --- a/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx +++ b/packages/widgets/src/_inputs/widget-sortable-item-list-input.tsx @@ -194,8 +194,6 @@ const Item = ({ return ( + - + Coolify - + oolify @@ -75,7 +75,11 @@ export function SingleInstanceLayout({ instance, options, isTiny, widgetKey }: S )} - + Coolify diff --git a/packages/widgets/src/coolify/types.ts b/packages/widgets/src/coolify/types.ts index a5982b695..3316c503a 100644 --- a/packages/widgets/src/coolify/types.ts +++ b/packages/widgets/src/coolify/types.ts @@ -3,6 +3,7 @@ import type { CoolifyInstanceInfo } from "@homarr/integrations/types"; import type { WidgetComponentProps } from "../definition"; export const COOLIFY_ICON_URL = "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/coolify.svg"; +export const COOLIFY_BRAND_COLOR = "#8B5CF6"; export interface InstanceData { integrationId: string; diff --git a/packages/widgets/src/docker/component.tsx b/packages/widgets/src/docker/component.tsx index c135484a8..e47c77f33 100644 --- a/packages/widgets/src/docker/component.tsx +++ b/packages/widgets/src/docker/component.tsx @@ -62,7 +62,7 @@ const createColumns = ( Cell({ renderedCellValue, row }) { return ( - + {renderedCellValue} diff --git a/packages/widgets/src/downloads/component.tsx b/packages/widgets/src/downloads/component.tsx index 2a96dc7cf..96e63a106 100644 --- a/packages/widgets/src/downloads/component.tsx +++ b/packages/widgets/src/downloads/component.tsx @@ -864,7 +864,7 @@ const ClientsControl = ({ clients, filters, setFilters, availableStatuses }: Cli - + {client.status ? ( diff --git a/packages/widgets/src/health-monitoring/cluster/resource-table.tsx b/packages/widgets/src/health-monitoring/cluster/resource-table.tsx index 1b0d4fe6f..13e75bc90 100644 --- a/packages/widgets/src/health-monitoring/cluster/resource-table.tsx +++ b/packages/widgets/src/health-monitoring/cluster/resource-table.tsx @@ -1,4 +1,4 @@ -import { Group, Indicator, Popover, Table, TableTbody, TableThead, TableTr, Text } from "@mantine/core"; +import { Group, Indicator, Popover, Table, TableTbody, TableTh, TableThead, TableTr, Text } from "@mantine/core"; import type { Resource } from "@homarr/integrations/types"; import { useI18n } from "@homarr/translation/client"; @@ -17,23 +17,23 @@ export const ResourceTable = ({ type, data, isTiny }: ResourceTableProps) => { - + {t("widget.healthMonitoring.cluster.table.header.name")} - + {type !== "storage" ? ( - + {t("widget.healthMonitoring.cluster.table.header.cpu")} - + ) : null} {type !== "storage" ? ( - + {t("widget.healthMonitoring.cluster.table.header.memory")} - + ) : null} {type === "storage" ? ( - + {t("widget.healthMonitoring.cluster.table.header.node")} - + ) : null} diff --git a/packages/widgets/src/media-requests/list/component.tsx b/packages/widgets/src/media-requests/list/component.tsx index 3015451bc..5d86c40a1 100644 --- a/packages/widgets/src/media-requests/list/component.tsx +++ b/packages/widgets/src/media-requests/list/component.tsx @@ -95,7 +95,6 @@ const MediaRequestCard = ({ request, isTiny, options }: MediaRequestCardProps) = className={`mediaRequests-list-item-wrapper mediaRequests-list-item-${request.type} mediaRequests-list-item-${request.status}`} radius={board.itemRadius} p="xs" - withBorder > variant="light" color="green" size="xs" - radius="md" onClick={() => { handleDecision("approve"); }} @@ -228,7 +226,6 @@ const DecisionButtons = ({ requestId, integrationId }: DecisionButtonsProps) => variant="light" color="red" size="xs" - radius="md" onClick={() => { handleDecision("decline"); }} diff --git a/packages/widgets/src/media-requests/stats/component.tsx b/packages/widgets/src/media-requests/stats/component.tsx index e3696ef47..4a1b6ed09 100644 --- a/packages/widgets/src/media-requests/stats/component.tsx +++ b/packages/widgets/src/media-requests/stats/component.tsx @@ -23,6 +23,9 @@ import type { WidgetComponentProps } from "../../definition"; import { NoIntegrationDataError } from "../../errors/no-data-integration"; import classes from "./component.module.css"; +const OVERSEERR_COLOR = "#ECB000"; +const JELLYSEERR_COLOR = "#6677CC"; + export default function MediaServerWidget({ integrationIds, isEditMode, @@ -151,7 +154,7 @@ export default function MediaServerWidget({ className="mediaRequests-stats-users-user-avatar" size={20} src={user.avatar} - bd={`2px solid ${user.integration.kind === "overseerr" ? "#ECB000" : "#6677CC"}`} + bd={`2px solid ${user.integration.kind === "overseerr" ? OVERSEERR_COLOR : JELLYSEERR_COLOR}`} /> diff --git a/packages/widgets/src/media-transcoding/health-check-status.tsx b/packages/widgets/src/media-transcoding/health-check-status.tsx index d1b3f7df9..24a8100d3 100644 --- a/packages/widgets/src/media-transcoding/health-check-status.tsx +++ b/packages/widgets/src/media-transcoding/health-check-status.tsx @@ -27,7 +27,11 @@ export function HealthCheckStatus(props: HealthCheckStatusProps) { - + diff --git a/packages/widgets/src/media-transcoding/panels/queue.panel.tsx b/packages/widgets/src/media-transcoding/panels/queue.panel.tsx index 45cc7581f..99e8e9e2a 100644 --- a/packages/widgets/src/media-transcoding/panels/queue.panel.tsx +++ b/packages/widgets/src/media-transcoding/panels/queue.panel.tsx @@ -1,4 +1,17 @@ -import { Center, Group, ScrollArea, Table, TableTd, TableTh, TableTr, Text, Title, Tooltip } from "@mantine/core"; +import { + Center, + Group, + ScrollArea, + Table, + TableTbody, + TableTd, + TableTh, + TableThead, + TableTr, + Text, + Title, + Tooltip, +} from "@mantine/core"; import { IconHeartbeat, IconTransform } from "@tabler/icons-react"; import { humanFileSize } from "@homarr/common"; @@ -25,7 +38,7 @@ export function QueuePanel(props: QueuePanelProps) { return (
- + @@ -38,8 +51,8 @@ export function QueuePanel(props: QueuePanelProps) { - - + + {queue.array.map((item) => ( @@ -63,7 +76,7 @@ export function QueuePanel(props: QueuePanelProps) { ))} - +
); diff --git a/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx b/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx index b80dab0dd..af7c4b15b 100644 --- a/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx +++ b/packages/widgets/src/media-transcoding/panels/statistics.panel.tsx @@ -91,7 +91,7 @@ function StatisticItem(props: StatisticItemProps) { const board = useRequiredBoard(); return ( - + {props.value} diff --git a/packages/widgets/src/media-transcoding/panels/workers.panel.tsx b/packages/widgets/src/media-transcoding/panels/workers.panel.tsx index d1602c248..3dbf968b7 100644 --- a/packages/widgets/src/media-transcoding/panels/workers.panel.tsx +++ b/packages/widgets/src/media-transcoding/panels/workers.panel.tsx @@ -4,8 +4,10 @@ import { Progress, ScrollArea, Table, + TableTbody, TableTd, TableTh, + TableThead, TableTr, Text, Title, @@ -35,7 +37,7 @@ export function WorkersPanel(props: WorkersPanelProps) { return ( - + @@ -53,8 +55,8 @@ export function WorkersPanel(props: WorkersPanelProps) { - - + + {props.workers.map((worker) => { const fileName = worker.filePath.split("\\").pop()?.split("/").pop() ?? worker.filePath; return ( @@ -101,7 +103,7 @@ export function WorkersPanel(props: WorkersPanelProps) { ); })} - +
); diff --git a/packages/widgets/src/notebook/notebook.tsx b/packages/widgets/src/notebook/notebook.tsx index e7377b4b9..97721daf7 100644 --- a/packages/widgets/src/notebook/notebook.tsx +++ b/packages/widgets/src/notebook/notebook.tsx @@ -421,7 +421,6 @@ export function Notebook({ options, setOptions, isEditMode, boardId, itemId }: W color={primaryColor} variant="light" size={30} - radius={"md"} onClick={handleEditToggle} > {isEditing ? : } @@ -438,7 +437,6 @@ export function Notebook({ options, setOptions, isEditMode, boardId, itemId }: W color={primaryColor} variant="light" size={30} - radius={"md"} onClick={handleEditCancel} > diff --git a/packages/widgets/src/notifications/component.tsx b/packages/widgets/src/notifications/component.tsx index 1fc4d6910..72a662956 100644 --- a/packages/widgets/src/notifications/component.tsx +++ b/packages/widgets/src/notifications/component.tsx @@ -67,7 +67,7 @@ export default function NotificationsWidget({ options, integrationIds }: WidgetC {sortedNotifications.length > 0 ? ( sortedNotifications.map((notification) => ( - + {notification.title && ( diff --git a/packages/widgets/src/releases/component.module.scss b/packages/widgets/src/releases/component.module.scss index 1fbdf7434..9d41454cb 100644 --- a/packages/widgets/src/releases/component.module.scss +++ b/packages/widgets/src/releases/component.module.scss @@ -1,10 +1,8 @@ .releasesRepository { - border-left: 2px solid transparent; - &:has(.releasesRepositoryHeader:hover), &:has(.releasesRepositoryHeader.active), &:has(.releasesRepositoryDetails:hover) { - border-left-color: var(--mantine-color-secondaryColor-text); + background-color: var(--mantine-color-secondaryColor-light); } } diff --git a/packages/widgets/src/rssFeed/component.tsx b/packages/widgets/src/rssFeed/component.tsx index f219cd2e4..843168b88 100644 --- a/packages/widgets/src/rssFeed/component.tsx +++ b/packages/widgets/src/rssFeed/component.tsx @@ -57,7 +57,6 @@ export default function RssFeed({ options, width }: WidgetComponentProps<"rssFee {feedEntries.map((feedEntry) => ( )} - +
diff --git a/packages/widgets/src/system-resources/chart/combined-network-traffic.tsx b/packages/widgets/src/system-resources/chart/combined-network-traffic.tsx index 6cfee0eaa..20b01bb58 100644 --- a/packages/widgets/src/system-resources/chart/combined-network-traffic.tsx +++ b/packages/widgets/src/system-resources/chart/combined-network-traffic.tsx @@ -38,7 +38,7 @@ export const CombinedNetworkTrafficChart = ({ tooltipProps={{ content: ({ payload }) => { return ( - + {payload.map((payloadData) => ( diff --git a/packages/widgets/src/system-resources/chart/cpu-chart.tsx b/packages/widgets/src/system-resources/chart/cpu-chart.tsx index 7006728d5..a799978ae 100644 --- a/packages/widgets/src/system-resources/chart/cpu-chart.tsx +++ b/packages/widgets/src/system-resources/chart/cpu-chart.tsx @@ -36,7 +36,7 @@ export const SystemResourceCPUChart = ({ content: ({ payload }) => { const value = payload[0] ? Number(payload[0].value) : 0; return ( - + {value.toFixed(0)}% diff --git a/packages/widgets/src/system-resources/chart/gpu-chart.tsx b/packages/widgets/src/system-resources/chart/gpu-chart.tsx index bf2d34b40..4efdb0bab 100644 --- a/packages/widgets/src/system-resources/chart/gpu-chart.tsx +++ b/packages/widgets/src/system-resources/chart/gpu-chart.tsx @@ -36,7 +36,7 @@ export const SystemResourceGPUChart = ({ content: ({ payload }) => { const value = payload[0] ? Number(payload[0].value) : 0; return ( - + {value.toFixed(0)}% diff --git a/packages/widgets/src/system-resources/chart/memory-chart.tsx b/packages/widgets/src/system-resources/chart/memory-chart.tsx index 54c2e347c..9de519199 100644 --- a/packages/widgets/src/system-resources/chart/memory-chart.tsx +++ b/packages/widgets/src/system-resources/chart/memory-chart.tsx @@ -42,7 +42,7 @@ export const SystemResourceMemoryChart = ({ content: ({ payload }) => { const value = payload[0] ? Number(payload[0].value) : 0; return ( - + {humanFileSize(Math.round(value))} / {humanFileSize(totalCapacityInBytes)} ( {Math.round((value / totalCapacityInBytes) * 100)}%) diff --git a/packages/widgets/src/system-resources/chart/network-traffic.tsx b/packages/widgets/src/system-resources/chart/network-traffic.tsx index 02747b86d..9dd0b6d04 100644 --- a/packages/widgets/src/system-resources/chart/network-traffic.tsx +++ b/packages/widgets/src/system-resources/chart/network-traffic.tsx @@ -39,7 +39,7 @@ export const NetworkTrafficChart = ({ content: ({ payload }) => { const value = payload[0] ? Number(payload[0].value) : 0; return ( - + {humanFileSize(Math.round(value))}/s diff --git a/packages/widgets/src/tracearr/recent-activity-section.tsx b/packages/widgets/src/tracearr/recent-activity-section.tsx index 84fe35c3b..e078fd6f2 100644 --- a/packages/widgets/src/tracearr/recent-activity-section.tsx +++ b/packages/widgets/src/tracearr/recent-activity-section.tsx @@ -24,7 +24,7 @@ export function RecentActivityList({ sessions }: { sessions: TracearrHistorySess : session.mediaTitle; return ( - + diff --git a/packages/widgets/src/tracearr/stats-section.tsx b/packages/widgets/src/tracearr/stats-section.tsx index efa2d8b32..60b4ef125 100644 --- a/packages/widgets/src/tracearr/stats-section.tsx +++ b/packages/widgets/src/tracearr/stats-section.tsx @@ -32,7 +32,7 @@ export function StatsBar({ function StatCard({ icon, label, value }: { icon: React.ReactNode; label: string; value: string | number }) { return ( - + {icon} diff --git a/packages/widgets/src/tracearr/streams-section.tsx b/packages/widgets/src/tracearr/streams-section.tsx index e7908b7ba..0b9d0a3bc 100644 --- a/packages/widgets/src/tracearr/streams-section.tsx +++ b/packages/widgets/src/tracearr/streams-section.tsx @@ -45,7 +45,7 @@ function StreamCard({ stream, compact }: { stream: TracearrStream; compact: bool : null; return ( - + {stream.posterUrl && ( - + {mediaLabel} diff --git a/packages/widgets/src/tracearr/violations-section.tsx b/packages/widgets/src/tracearr/violations-section.tsx index a35c5a933..2ce675ed8 100644 --- a/packages/widgets/src/tracearr/violations-section.tsx +++ b/packages/widgets/src/tracearr/violations-section.tsx @@ -19,7 +19,7 @@ export function ViolationsList({ violations }: { violations: TracearrViolation[] ) : ( {violations.map((violation) => ( - +