Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0270dae3d6 | ||
|
|
19a4bee334 | ||
|
|
60f9d4e6e6 | ||
|
|
7d3322576c | ||
|
|
1842e5fff5 | ||
|
|
1b70973084 | ||
|
|
b4ac3fc346 | ||
|
|
4904f5c270 | ||
|
|
15b4dfed0f | ||
|
|
a853463ade | ||
|
|
9dd00370ff | ||
|
|
fad478c549 | ||
|
|
9b0dd6d6ce | ||
|
|
acb0bc68d2 | ||
|
|
45d2102d38 | ||
|
|
72baf965b4 | ||
|
|
808ace3983 | ||
|
|
1e5d38fd3c | ||
|
|
bf44a8ecb1 | ||
|
|
236fa35f7e | ||
|
|
a004bfbb9e | ||
|
|
e574dd70f1 | ||
|
|
249d929435 | ||
|
|
e40a11608c | ||
|
|
1f1a5f2583 | ||
|
|
d00270046a | ||
|
|
809bf559fe | ||
|
|
67600ff687 | ||
|
|
9191430229 | ||
|
|
49afb82446 | ||
|
|
f04f53759b | ||
|
|
7712ab410b | ||
|
|
1c727e59af | ||
|
|
8b096939e4 | ||
|
|
adaa8039dd |
No files matched your search
@@ -33,6 +33,9 @@ body:
|
||||
options:
|
||||
# The below comment is used to insert a new version with on-release.yml
|
||||
#NEXT_VERSION#
|
||||
- 1.49.0
|
||||
- 1.48.0
|
||||
- 1.47.0
|
||||
- 1.46.0
|
||||
- 1.45.3
|
||||
- 1.45.2
|
||||
|
||||
@@ -1,3 +1,35 @@
|
||||
## [1.49.1](https://github.com/homarr-labs/homarr/compare/v1.49.0...v1.49.1) (2026-01-03)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **db:** connection issue do to missing host and name of db when connecting with host ([#4786](https://github.com/homarr-labs/homarr/issues/4786)) ([7d33225](https://github.com/homarr-labs/homarr/commit/7d3322576c3ed1b9917873bf707d77d2a4eef1a8))
|
||||
* **deps:** update dependency ldapts to v8.0.36 ([#4790](https://github.com/homarr-labs/homarr/issues/4790)) ([1842e5f](https://github.com/homarr-labs/homarr/commit/1842e5fff5c072c8da45a01be860e63d12d5062a))
|
||||
* **deps:** update dependency react-error-boundary to ^6.0.1 ([#4791](https://github.com/homarr-labs/homarr/issues/4791)) ([1b70973](https://github.com/homarr-labs/homarr/commit/1b70973084c9e9ebed34e8d7d9690a9e5530f60f))
|
||||
* **unraid:** temperature of disks can be null ([#4788](https://github.com/homarr-labs/homarr/issues/4788)) ([60f9d4e](https://github.com/homarr-labs/homarr/commit/60f9d4e6e69df2190171e5d8e263b2030447ab2e))
|
||||
|
||||
## [1.49.0](https://github.com/homarr-labs/homarr/compare/v1.48.0...v1.49.0) (2026-01-02)
|
||||
|
||||
### Features
|
||||
|
||||
* unraid integration ([#4439](https://github.com/homarr-labs/homarr/issues/4439)) ([9b0dd6d](https://github.com/homarr-labs/homarr/commit/9b0dd6d6cebda4a541c8859506d89e9e9f782fa4))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add orphaned status for containers with invalid stats ([#4441](https://github.com/homarr-labs/homarr/issues/4441)) ([f04f537](https://github.com/homarr-labs/homarr/commit/f04f53759b6890d5d2dd683a9bf124d8ff12780b))
|
||||
* **deps:** update dependency @xterm/addon-fit to v0.11.0 ([#4756](https://github.com/homarr-labs/homarr/issues/4756)) ([1c727e5](https://github.com/homarr-labs/homarr/commit/1c727e59af4041e5e41da854633ccd3c030c1d18))
|
||||
* **deps:** update dependency @xterm/xterm to v6 ([#4757](https://github.com/homarr-labs/homarr/issues/4757)) ([fad478c](https://github.com/homarr-labs/homarr/commit/fad478c549cdbc616f921d9b444bff48b59e77a5))
|
||||
* **deps:** update dependency isomorphic-dompurify to ^2.35.0 ([#4779](https://github.com/homarr-labs/homarr/issues/4779)) ([236fa35](https://github.com/homarr-labs/homarr/commit/236fa35f7e0943be33bba153e7030ce4e3bb204e))
|
||||
* **deps:** update dependency jotai to ^2.16.1 ([#4772](https://github.com/homarr-labs/homarr/issues/4772)) ([d002700](https://github.com/homarr-labs/homarr/commit/d00270046a041a10c1c540cfa79c1eee477f3303))
|
||||
* **deps:** update dependency ldapts to v8.0.31 ([#4755](https://github.com/homarr-labs/homarr/issues/4755)) ([8b09693](https://github.com/homarr-labs/homarr/commit/8b096939e4e1da8e98791a8e05f108a136fe2810))
|
||||
* **deps:** update dependency ldapts to v8.0.32 ([#4762](https://github.com/homarr-labs/homarr/issues/4762)) ([49afb82](https://github.com/homarr-labs/homarr/commit/49afb8244615f67af0586aaacf77a509231ac6dc))
|
||||
* **deps:** update dependency ldapts to v8.0.34 ([#4765](https://github.com/homarr-labs/homarr/issues/4765)) ([809bf55](https://github.com/homarr-labs/homarr/commit/809bf559fe1b96df9a903dc790d138cad7368adb))
|
||||
* **deps:** update dependency ldapts to v8.0.35 ([#4768](https://github.com/homarr-labs/homarr/issues/4768)) ([e574dd7](https://github.com/homarr-labs/homarr/commit/e574dd70f1421e9254a289a0f02fd0b4d43e26ad))
|
||||
* **deps:** update dependency typescript-eslint to ^8.50.1 ([#4758](https://github.com/homarr-labs/homarr/issues/4758)) ([adaa803](https://github.com/homarr-labs/homarr/commit/adaa8039dd545109246ccd9fa15570739f755f62))
|
||||
* **deps:** update nextjs monorepo to v16.1.1 ([#4759](https://github.com/homarr-labs/homarr/issues/4759)) ([7712ab4](https://github.com/homarr-labs/homarr/commit/7712ab410b5094e5d84df75461e07efdfccc285b))
|
||||
* **deps:** update tanstack-query monorepo ([#4782](https://github.com/homarr-labs/homarr/issues/4782)) ([1e5d38f](https://github.com/homarr-labs/homarr/commit/1e5d38fd3ca4c68fa4c61b02757a3cff39839fdb))
|
||||
* **deps:** update testcontainers-node monorepo to ^11.11.0 ([#4781](https://github.com/homarr-labs/homarr/issues/4781)) ([e40a116](https://github.com/homarr-labs/homarr/commit/e40a11608cb21a75e6910028abf97e14b5275f56))
|
||||
* **deps:** update turbo monorepo to ^2.7.2 ([#4764](https://github.com/homarr-labs/homarr/issues/4764)) ([9191430](https://github.com/homarr-labs/homarr/commit/919143022969350f6ee7be2f53be2fe09a89bba3))
|
||||
|
||||
## [1.48.0](https://github.com/homarr-labs/homarr/compare/v1.47.0...v1.48.0) (2025-12-26)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -56,16 +56,16 @@
|
||||
"@mantine/tiptap": "^8.3.10",
|
||||
"@million/lint": "1.0.14",
|
||||
"@tabler/icons-react": "^3.35.0",
|
||||
"@tanstack/react-query": "^5.90.12",
|
||||
"@tanstack/react-query-devtools": "^5.91.1",
|
||||
"@tanstack/react-query": "^5.90.14",
|
||||
"@tanstack/react-query-devtools": "^5.91.2",
|
||||
"@tanstack/react-query-next-experimental": "^5.91.0",
|
||||
"@trpc/client": "^11.8.1",
|
||||
"@trpc/next": "^11.8.1",
|
||||
"@trpc/react-query": "^11.8.1",
|
||||
"@trpc/server": "^11.8.1",
|
||||
"@xterm/addon-canvas": "^0.7.0",
|
||||
"@xterm/addon-fit": "0.10.0",
|
||||
"@xterm/xterm": "^5.5.0",
|
||||
"@xterm/addon-fit": "0.11.0",
|
||||
"@xterm/xterm": "^6.0.0",
|
||||
"babel-plugin-react-compiler": "^1.0.0",
|
||||
"chroma-js": "^3.2.0",
|
||||
"clsx": "^2.1.1",
|
||||
@@ -73,15 +73,15 @@
|
||||
"dotenv": "^17.2.3",
|
||||
"flag-icons": "^7.5.0",
|
||||
"glob": "^13.0.0",
|
||||
"isomorphic-dompurify": "^2.34.0",
|
||||
"jotai": "^2.16.0",
|
||||
"isomorphic-dompurify": "^2.35.0",
|
||||
"jotai": "^2.16.1",
|
||||
"mantine-react-table": "2.0.0-beta.9",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"postcss-preset-mantine": "^1.18.0",
|
||||
"prismjs": "^1.30.0",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"react-error-boundary": "^6.0.0",
|
||||
"react-error-boundary": "^6.0.1",
|
||||
"react-simple-code-editor": "^0.14.1",
|
||||
"sass": "^1.97.1",
|
||||
"superjson": "2.2.6",
|
||||
|
||||
@@ -76,6 +76,7 @@ const createColumns = (
|
||||
accessorKey: "ports",
|
||||
header: t("docker.field.ports.label"),
|
||||
Cell({ cell }) {
|
||||
if (!cell.row.original.ports.length) return null;
|
||||
return (
|
||||
<OverflowBadge overflowCount={1} data={cell.row.original.ports.map((port) => port.PrivatePort.toString())} />
|
||||
);
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||
"@types/node": "^24.10.4",
|
||||
"dotenv-cli": "^11.0.0",
|
||||
"esbuild": "^0.27.1",
|
||||
"esbuild": "^0.27.2",
|
||||
"eslint": "^9.39.2",
|
||||
"prettier": "^3.7.4",
|
||||
"tsx": "4.20.4",
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||
"@types/ws": "^8.18.1",
|
||||
"esbuild": "^0.27.1",
|
||||
"esbuild": "^0.27.2",
|
||||
"eslint": "^9.39.2",
|
||||
"prettier": "^3.7.4",
|
||||
"typescript": "^5.9.3"
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
"dependencies": {
|
||||
"better-sqlite3": "^12.5.0"
|
||||
},
|
||||
"packageManager": "pnpm@10.26.1",
|
||||
"packageManager": "pnpm@10.26.2",
|
||||
"engines": {
|
||||
"node": ">=24.12.0",
|
||||
"pnpm": ">=10.26.1"
|
||||
"pnpm": ">=10.26.2"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
|
||||
@@ -314,6 +314,13 @@
|
||||
<br/>
|
||||
<p align="center">Unifi<br/>Controller</p>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://homarr.dev/docs/integrations/unraid" target="_blank" rel="noreferrer noopener">
|
||||
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/unraid.svg" alt="Unraid" width="90" height="90" />
|
||||
<br/>
|
||||
<p align="center">Unraid</p>
|
||||
</a>
|
||||
</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
+11
-11
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "homarr",
|
||||
"version": "1.48.0",
|
||||
"version": "1.49.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "cross-env CI=true turbo build",
|
||||
@@ -42,27 +42,27 @@
|
||||
"@semantic-release/github": "^12.0.2",
|
||||
"@semantic-release/npm": "^13.1.3",
|
||||
"@semantic-release/release-notes-generator": "^14.1.0",
|
||||
"@testcontainers/redis": "^11.10.0",
|
||||
"@turbo/gen": "^2.7.1",
|
||||
"@testcontainers/redis": "^11.11.0",
|
||||
"@turbo/gen": "^2.7.2",
|
||||
"@vitejs/plugin-react": "^5.1.2",
|
||||
"@vitest/coverage-v8": "^4.0.16",
|
||||
"@vitest/ui": "^4.0.16",
|
||||
"conventional-changelog-conventionalcommits": "^9.1.0",
|
||||
"cross-env": "^10.1.0",
|
||||
"jsdom": "^27.3.0",
|
||||
"jsdom": "^27.4.0",
|
||||
"json5": "^2.2.3",
|
||||
"prettier": "^3.7.4",
|
||||
"semantic-release": "^25.0.2",
|
||||
"testcontainers": "^11.10.0",
|
||||
"turbo": "^2.7.1",
|
||||
"testcontainers": "^11.11.0",
|
||||
"turbo": "^2.7.2",
|
||||
"typescript": "^5.9.3",
|
||||
"vite-tsconfig-paths": "^5.1.4",
|
||||
"vite-tsconfig-paths": "^6.0.3",
|
||||
"vitest": "^4.0.16"
|
||||
},
|
||||
"packageManager": "pnpm@10.26.1",
|
||||
"packageManager": "pnpm@10.26.2",
|
||||
"engines": {
|
||||
"node": ">=24.12.0",
|
||||
"pnpm": ">=10.26.1"
|
||||
"pnpm": ">=10.26.2"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
@@ -82,9 +82,9 @@
|
||||
"axios@>=1.0.0 <1.8.2": ">=1.13.2",
|
||||
"brace-expansion@>=2.0.0 <=2.0.1": ">=4.0.1",
|
||||
"brace-expansion@>=1.0.0 <=1.1.11": ">=4.0.1",
|
||||
"esbuild@<=0.24.2": ">=0.27.1",
|
||||
"esbuild@<=0.24.2": ">=0.27.2",
|
||||
"form-data@>=4.0.0 <4.0.4": ">=4.0.5",
|
||||
"hono@<4.6.5": ">=4.11.1",
|
||||
"hono@<4.6.5": ">=4.11.3",
|
||||
"linkifyjs@<4.3.2": ">=4.3.2",
|
||||
"nanoid@>=4.0.0 <5.0.9": ">=5.1.6",
|
||||
"prismjs@<1.30.0": ">=1.30.0",
|
||||
|
||||
@@ -41,13 +41,13 @@
|
||||
"@homarr/translation": "workspace:^0.1.0",
|
||||
"@homarr/validation": "workspace:^0.1.0",
|
||||
"@kubernetes/client-node": "^1.4.0",
|
||||
"@tanstack/react-query": "^5.90.12",
|
||||
"@tanstack/react-query": "^5.90.14",
|
||||
"@trpc/client": "^11.8.1",
|
||||
"@trpc/react-query": "^11.8.1",
|
||||
"@trpc/server": "^11.8.1",
|
||||
"@trpc/tanstack-react-query": "^11.8.1",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"superjson": "2.2.6",
|
||||
|
||||
@@ -9,7 +9,7 @@ import { createTRPCRouter, publicProcedure } from "../../trpc";
|
||||
|
||||
export const healthMonitoringRouter = createTRPCRouter({
|
||||
getSystemHealthStatus: publicProcedure
|
||||
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "mock"))
|
||||
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "unraid", "mock"))
|
||||
.query(async ({ ctx }) => {
|
||||
return await Promise.all(
|
||||
ctx.integrations.map(async (integration) => {
|
||||
@@ -26,7 +26,7 @@ export const healthMonitoringRouter = createTRPCRouter({
|
||||
);
|
||||
}),
|
||||
subscribeSystemHealthStatus: publicProcedure
|
||||
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "mock"))
|
||||
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "unraid", "mock"))
|
||||
.subscription(({ ctx }) => {
|
||||
return observable<{ integrationId: string; healthInfo: SystemHealthMonitoring; timestamp: Date }>((emit) => {
|
||||
const unsubscribes: (() => void)[] = [];
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
"@homarr/validation": "workspace:^0.1.0",
|
||||
"bcrypt": "^6.0.0",
|
||||
"cookies": "^0.9.1",
|
||||
"ldapts": "8.0.30",
|
||||
"next": "16.1.0",
|
||||
"ldapts": "8.0.36",
|
||||
"next": "16.1.1",
|
||||
"next-auth": "5.0.0-beta.30",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||
"esbuild": "^0.27.1",
|
||||
"esbuild": "^0.27.2",
|
||||
"eslint": "^9.39.2",
|
||||
"typescript": "^5.9.3"
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"@homarr/core": "workspace:^0.1.0",
|
||||
"@paralleldrive/cuid2": "^3.1.0",
|
||||
"dayjs": "^1.11.19",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"octokit": "^5.0.5",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
|
||||
@@ -26,7 +26,9 @@ const createMysqlDbConnection = () => {
|
||||
|
||||
return mysql.createPool({
|
||||
...defaultOptions,
|
||||
host: dbEnv.HOST,
|
||||
port: dbEnv.PORT,
|
||||
database: dbEnv.NAME,
|
||||
user: dbEnv.USER,
|
||||
password: dbEnv.PASSWORD,
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
"@homarr/common": "workspace:^0.1.0",
|
||||
"@homarr/core": "workspace:^0.1.0",
|
||||
"@homarr/cron-jobs": "workspace:^0.1.0",
|
||||
"@tanstack/react-query": "^5.90.12",
|
||||
"@tanstack/react-query": "^5.90.14",
|
||||
"@trpc/client": "^11.8.1",
|
||||
"@trpc/server": "^11.8.1",
|
||||
"@trpc/tanstack-react-query": "^11.8.1",
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
"@homarr/server-settings": "workspace:^0.1.0",
|
||||
"@mantine/core": "^8.3.10",
|
||||
"@paralleldrive/cuid2": "^3.1.0",
|
||||
"@testcontainers/mysql": "^11.10.0",
|
||||
"@testcontainers/postgresql": "^11.10.0",
|
||||
"@testcontainers/mysql": "^11.11.0",
|
||||
"@testcontainers/postgresql": "^11.11.0",
|
||||
"better-sqlite3": "^12.5.0",
|
||||
"dotenv": "^17.2.3",
|
||||
"drizzle-kit": "^0.31.8",
|
||||
@@ -67,7 +67,7 @@
|
||||
"@types/better-sqlite3": "7.6.13",
|
||||
"@types/pg": "^8.16.0",
|
||||
"dotenv-cli": "^11.0.0",
|
||||
"esbuild": "^0.27.1",
|
||||
"esbuild": "^0.27.2",
|
||||
"eslint": "^9.39.2",
|
||||
"prettier": "^3.7.4",
|
||||
"tsx": "4.20.4",
|
||||
|
||||
@@ -188,6 +188,7 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/integrations/transmission"
|
||||
| "/docs/integrations/truenas"
|
||||
| "/docs/integrations/unifi-controller"
|
||||
| "/docs/integrations/unraid"
|
||||
| "/docs/management/api"
|
||||
| "/docs/management/apps"
|
||||
| "/docs/management/boards"
|
||||
|
||||
@@ -298,6 +298,13 @@ export const integrationDefs = {
|
||||
category: ["healthMonitoring"],
|
||||
documentationUrl: createDocumentationLink("/docs/integrations/truenas"),
|
||||
},
|
||||
unraid: {
|
||||
name: "Unraid",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/unraid.svg",
|
||||
category: ["healthMonitoring"],
|
||||
documentationUrl: createDocumentationLink("/docs/integrations/unraid"),
|
||||
},
|
||||
// This integration only returns mock data, it is used during development (but can also be used in production by directly going to the create page)
|
||||
mock: {
|
||||
name: "Mock",
|
||||
|
||||
@@ -38,6 +38,7 @@ import { ProxmoxIntegration } from "../proxmox/proxmox-integration";
|
||||
import { QuayIntegration } from "../quay/quay-integration";
|
||||
import { TrueNasIntegration } from "../truenas/truenas-integration";
|
||||
import { UnifiControllerIntegration } from "../unifi-controller/unifi-controller-integration";
|
||||
import { UnraidIntegration } from "../unraid/unraid-integration";
|
||||
import type { Integration, IntegrationInput } from "./integration";
|
||||
|
||||
export const createIntegrationAsync = async <TKind extends keyof typeof integrationCreators>(
|
||||
@@ -101,6 +102,7 @@ export const integrationCreators = {
|
||||
ntfy: NTFYIntegration,
|
||||
mock: MockIntegration,
|
||||
truenas: TrueNasIntegration,
|
||||
unraid: UnraidIntegration,
|
||||
} satisfies Record<IntegrationKind, IntegrationInstance | [(input: IntegrationInput) => Promise<Integration>]>;
|
||||
|
||||
type IntegrationInstanceOfKind<TKind extends keyof typeof integrationCreators> = {
|
||||
|
||||
@@ -22,6 +22,7 @@ export { PiHoleIntegrationV6 } from "./pi-hole/v6/pi-hole-integration-v6";
|
||||
export { PlexIntegration } from "./plex/plex-integration";
|
||||
export { ProwlarrIntegration } from "./prowlarr/prowlarr-integration";
|
||||
export { TrueNasIntegration } from "./truenas/truenas-integration";
|
||||
export { UnraidIntegration } from "./unraid/unraid-integration";
|
||||
export { OPNsenseIntegration } from "./opnsense/opnsense-integration";
|
||||
export { ICalIntegration } from "./ical/ical-integration";
|
||||
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
import dayjs from "dayjs";
|
||||
import type { fetch as undiciFetch } from "undici/types/fetch";
|
||||
|
||||
import { humanFileSize } from "@homarr/common";
|
||||
import { ResponseError } from "@homarr/common/server";
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/core/infrastructure/http";
|
||||
import { createLogger } from "@homarr/core/infrastructure/logs";
|
||||
|
||||
import { HandleIntegrationErrors } from "../base/errors/decorator";
|
||||
import type { IntegrationTestingInput } from "../base/integration";
|
||||
import { Integration } from "../base/integration";
|
||||
import type { TestingResult } from "../base/test-connection/test-connection-service";
|
||||
import type { ISystemHealthMonitoringIntegration } from "../interfaces/health-monitoring/health-monitoring-integration";
|
||||
import type { SystemHealthMonitoring } from "../interfaces/health-monitoring/health-monitoring-types";
|
||||
import type { UnraidSystemInfo } from "./unraid-types";
|
||||
import { unraidSystemInfoSchema } from "./unraid-types";
|
||||
|
||||
const logger = createLogger({ module: "UnraidIntegration" });
|
||||
|
||||
@HandleIntegrationErrors([])
|
||||
export class UnraidIntegration extends Integration implements ISystemHealthMonitoringIntegration {
|
||||
protected async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
|
||||
await this.queryGraphQLAsync<{ info: UnraidSystemInfo }>(
|
||||
`
|
||||
query {
|
||||
info {
|
||||
os { platform }
|
||||
}
|
||||
}
|
||||
`,
|
||||
input.fetchAsync,
|
||||
);
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
public async getSystemInfoAsync(): Promise<SystemHealthMonitoring> {
|
||||
const systemInfo = await this.getSystemInformationAsync();
|
||||
|
||||
const cpuUtilization = systemInfo.metrics.cpu.cpus.reduce((acc, val) => acc + val.percentTotal, 0);
|
||||
const cpuCount = systemInfo.info.cpu.cores;
|
||||
|
||||
// We use "info" object instead of the stats since this is the exact amount the kernel sees, which is what Unraid displays.
|
||||
const totalMemory = systemInfo.info.memory.layout.reduce((acc, layout) => layout.size + acc, 0);
|
||||
const usedMemory = totalMemory * (systemInfo.metrics.memory.percentTotal / 100);
|
||||
const uptime = dayjs(systemInfo.info.os.uptime);
|
||||
|
||||
return {
|
||||
version: systemInfo.info.os.release,
|
||||
cpuModelName: systemInfo.info.cpu.brand,
|
||||
cpuUtilization: cpuUtilization / cpuCount,
|
||||
memUsedInBytes: usedMemory,
|
||||
memAvailableInBytes: totalMemory - usedMemory,
|
||||
uptime: dayjs().diff(uptime, "seconds"),
|
||||
network: null, // Not implemented, see https://github.com/unraid/api/issues/1602
|
||||
loadAverage: null,
|
||||
rebootRequired: false,
|
||||
availablePkgUpdates: 0,
|
||||
cpuTemp: undefined, // Not implemented, see https://github.com/unraid/api/issues/1597
|
||||
fileSystem: systemInfo.array.disks.map((disk) => ({
|
||||
deviceName: disk.name,
|
||||
used: humanFileSize(disk.fsUsed * 1024), // API is in KiB (kibibytes), covert to bytes
|
||||
available: `${disk.size * 1024}`, // API is in KiB (kibibytes), covert to bytes
|
||||
percentage: (disk.fsUsed / disk.size) * 100, // The units are the same, therefore the actual unit is irrelevant
|
||||
})),
|
||||
smart: systemInfo.array.disks.map((disk) => ({
|
||||
deviceName: disk.name,
|
||||
temperature: disk.temp ?? null,
|
||||
overallStatus: disk.status,
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
private async getSystemInformationAsync(): Promise<UnraidSystemInfo> {
|
||||
logger.debug("Retrieving system information", {
|
||||
url: this.url("/graphql"),
|
||||
});
|
||||
|
||||
const query = `
|
||||
query {
|
||||
metrics {
|
||||
cpu {
|
||||
percentTotal
|
||||
cpus {
|
||||
percentTotal
|
||||
}
|
||||
},
|
||||
memory {
|
||||
available
|
||||
used
|
||||
free
|
||||
total
|
||||
swapFree
|
||||
swapTotal
|
||||
swapUsed
|
||||
percentTotal
|
||||
}
|
||||
}
|
||||
array {
|
||||
state
|
||||
capacity {
|
||||
disks {
|
||||
free
|
||||
total
|
||||
used
|
||||
}
|
||||
}
|
||||
disks {
|
||||
name
|
||||
size
|
||||
fsFree
|
||||
fsUsed
|
||||
status
|
||||
temp
|
||||
}
|
||||
}
|
||||
info {
|
||||
devices {
|
||||
network {
|
||||
speed
|
||||
dhcp
|
||||
model
|
||||
model
|
||||
}
|
||||
}
|
||||
os {
|
||||
platform,
|
||||
distro,
|
||||
release,
|
||||
uptime
|
||||
},
|
||||
cpu {
|
||||
manufacturer,
|
||||
brand,
|
||||
cores,
|
||||
threads
|
||||
},
|
||||
memory {
|
||||
layout {
|
||||
size
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const response = await this.queryGraphQLAsync<UnraidSystemInfo>(query);
|
||||
const result = await unraidSystemInfoSchema.parseAsync(response);
|
||||
|
||||
logger.debug("Retrieved system information", {
|
||||
url: this.url("/graphql"),
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async queryGraphQLAsync<T>(
|
||||
query: string,
|
||||
fetchAsync: typeof undiciFetch = fetchWithTrustedCertificatesAsync,
|
||||
): Promise<T> {
|
||||
const url = this.url("/graphql");
|
||||
const apiKey = this.getSecretValue("apiKey");
|
||||
|
||||
logger.debug("Sending GraphQL query", {
|
||||
url: url.toString(),
|
||||
});
|
||||
|
||||
const response = await fetchAsync(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"x-api-key": apiKey,
|
||||
},
|
||||
body: JSON.stringify({ query }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new ResponseError(response);
|
||||
}
|
||||
|
||||
const json = (await response.json()) as { data: T; errors?: { message: string }[] };
|
||||
|
||||
if (json.errors) {
|
||||
throw new Error(`GraphQL errors: ${json.errors.map((error) => error.message).join(", ")}`);
|
||||
}
|
||||
|
||||
return json.data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import z from "zod";
|
||||
|
||||
export const unraidSystemInfoSchema = z.object({
|
||||
metrics: z.object({
|
||||
cpu: z.object({
|
||||
percentTotal: z.number(),
|
||||
cpus: z.array(
|
||||
z.object({
|
||||
percentTotal: z.number(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
memory: z.object({
|
||||
available: z.number(),
|
||||
used: z.number(),
|
||||
free: z.number(),
|
||||
total: z.number().min(0),
|
||||
percentTotal: z.number().min(0).max(100),
|
||||
}),
|
||||
}),
|
||||
array: z.object({
|
||||
state: z.string(),
|
||||
capacity: z.object({
|
||||
disks: z.object({
|
||||
free: z.coerce.number(),
|
||||
total: z.coerce.number(),
|
||||
used: z.coerce.number(),
|
||||
}),
|
||||
}),
|
||||
disks: z.array(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
size: z.number(),
|
||||
fsFree: z.number(),
|
||||
fsUsed: z.number(),
|
||||
status: z.string(),
|
||||
temp: z.number().nullish(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
info: z.object({
|
||||
devices: z.object({
|
||||
network: z.array(
|
||||
z.object({
|
||||
speed: z.number(),
|
||||
dhcp: z.boolean(),
|
||||
model: z.string(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
os: z.object({
|
||||
platform: z.string(),
|
||||
distro: z.string(),
|
||||
release: z.string(),
|
||||
uptime: z.coerce.date(),
|
||||
}),
|
||||
cpu: z.object({
|
||||
manufacturer: z.string(),
|
||||
brand: z.string(),
|
||||
cores: z.number(),
|
||||
threads: z.number(),
|
||||
}),
|
||||
memory: z.object({
|
||||
layout: z.array(
|
||||
z.object({
|
||||
size: z.number(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export type UnraidSystemInfo = z.infer<typeof unraidSystemInfoSchema>;
|
||||
@@ -36,7 +36,7 @@
|
||||
"@mantine/core": "^8.3.10",
|
||||
"@tabler/icons-react": "^3.35.0",
|
||||
"dayjs": "^1.11.19",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"zod": "^4.2.1"
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"@mantine/core": "^8.3.10",
|
||||
"@mantine/hooks": "^8.3.10",
|
||||
"adm-zip": "0.5.16",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"superjson": "2.2.6",
|
||||
|
||||
@@ -12,9 +12,7 @@ export const dockerContainersRequestHandler = createCachedWidgetRequestHandler({
|
||||
queryKey: "dockerContainersResult",
|
||||
widgetKind: "dockerContainers",
|
||||
async requestAsync() {
|
||||
const containers = await getContainersWithStatsAsync();
|
||||
|
||||
return containers;
|
||||
return await getContainersWithStatsAsync();
|
||||
},
|
||||
cacheDuration: dayjs.duration(20, "seconds"),
|
||||
});
|
||||
@@ -28,7 +26,7 @@ async function getContainersWithStatsAsync() {
|
||||
dockerInstances.map(async ({ instance, host }) => {
|
||||
const instanceContainers = await instance.listContainers({ all: true });
|
||||
return instanceContainers
|
||||
.filter((container) => dockerLabels.hide in container.Labels === false)
|
||||
.filter((container) => !(dockerLabels.hide in container.Labels))
|
||||
.map((container) => ({ ...container, instance: host }));
|
||||
}),
|
||||
).then((res) => res.flat());
|
||||
@@ -45,7 +43,21 @@ async function getContainersWithStatsAsync() {
|
||||
const instance = dockerInstances.find(({ host }) => host === container.instance)?.instance;
|
||||
if (!instance) return null;
|
||||
|
||||
const stats = await instance.getContainer(container.Id).stats({ stream: false, "one-shot": true });
|
||||
// Get stats, falling back to an empty stats object if fetch fails
|
||||
// calculateCpuUsage and calculateMemoryUsage will return 0 for invalid/missing stats
|
||||
const stats = await instance
|
||||
.getContainer(container.Id)
|
||||
.stats({ stream: false, "one-shot": true })
|
||||
.catch(
|
||||
() =>
|
||||
({
|
||||
cpu_stats: { online_cpus: 0, cpu_usage: { total_usage: 0 }, system_cpu_usage: 0 },
|
||||
memory_stats: { usage: 0 },
|
||||
}) as ContainerStats,
|
||||
);
|
||||
|
||||
const cpuUsage = calculateCpuUsage(stats);
|
||||
const memoryUsage = calculateMemoryUsage(stats);
|
||||
|
||||
return {
|
||||
id: container.Id,
|
||||
@@ -57,19 +69,8 @@ async function getContainersWithStatsAsync() {
|
||||
if (!extractedImage) return false;
|
||||
return icon.name.toLowerCase().includes(extractedImage.toLowerCase());
|
||||
})?.url ?? null,
|
||||
cpuUsage: calculateCpuUsage(stats),
|
||||
// memory usage by default includes cache, which should not be shown as it is also not shown with docker stats command
|
||||
// The below type is probably wrong, sometimes stats can be undefined
|
||||
// See https://docs.docker.com/reference/cli/docker/container/stats/ how it is / was calculated
|
||||
memoryUsage:
|
||||
stats.memory_stats.usage -
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
(stats.memory_stats.stats?.cache ??
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
stats.memory_stats.stats?.total_inactive_file ??
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
stats.memory_stats.stats?.inactive_file ??
|
||||
0),
|
||||
cpuUsage,
|
||||
memoryUsage,
|
||||
image: container.Image,
|
||||
ports: container.Ports,
|
||||
};
|
||||
@@ -79,10 +80,36 @@ async function getContainersWithStatsAsync() {
|
||||
}
|
||||
|
||||
function calculateCpuUsage(stats: ContainerStats): number {
|
||||
const numberOfCpus = stats.cpu_stats.online_cpus || 1;
|
||||
// Handle containers with missing or invalid stats (e.g., exited, dead containers)
|
||||
if (!stats.cpu_stats.online_cpus || stats.cpu_stats.online_cpus === 0 || !stats.cpu_stats.cpu_usage.total_usage) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const numberOfCpus = stats.cpu_stats.online_cpus;
|
||||
const usage = stats.cpu_stats.system_cpu_usage;
|
||||
if (usage === 0) return 0;
|
||||
if (!usage || usage === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (stats.cpu_stats.cpu_usage.total_usage / usage) * numberOfCpus * 100;
|
||||
}
|
||||
|
||||
function calculateMemoryUsage(stats: ContainerStats): number {
|
||||
// Handle containers with missing or invalid stats (e.g., exited, dead containers)
|
||||
if (!stats.memory_stats.usage) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// memory usage by default includes cache, which should not be shown as it is also not shown with docker stats command
|
||||
// See https://docs.docker.com/reference/cli/docker/container/stats/ how it is / was calculated
|
||||
return (
|
||||
stats.memory_stats.usage -
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
(stats.memory_stats.stats?.cache ??
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
stats.memory_stats.stats?.total_inactive_file ??
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
stats.memory_stats.stats?.inactive_file ??
|
||||
0)
|
||||
);
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
"@homarr/db": "workspace:^0.1.0",
|
||||
"@homarr/server-settings": "workspace:^0.1.0",
|
||||
"@mantine/dates": "^8.3.10",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3"
|
||||
},
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
"@mantine/hooks": "^8.3.10",
|
||||
"@mantine/spotlight": "^8.3.10",
|
||||
"@tabler/icons-react": "^3.35.0",
|
||||
"jotai": "^2.16.0",
|
||||
"next": "16.1.0",
|
||||
"jotai": "^2.16.1",
|
||||
"next": "16.1.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"use-deep-compare-effect": "^1.8.1"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"dayjs": "^1.11.19",
|
||||
"deepmerge": "4.3.1",
|
||||
"mantine-react-table": "2.0.0-beta.9",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"next-intl": "4.6.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3"
|
||||
|
||||
@@ -1941,19 +1941,19 @@
|
||||
"description": "Estadísticas de tus contenedores (Este widget sólo puede ser añadido con privilegios de administrador)",
|
||||
"option": {
|
||||
"enableRowSorting": {
|
||||
"label": ""
|
||||
"label": "Habilitar ordenar elementos"
|
||||
},
|
||||
"defaultSort": {
|
||||
"label": "",
|
||||
"label": "Columna usada para ordenar por defecto",
|
||||
"option": {
|
||||
"name": "",
|
||||
"state": "",
|
||||
"cpuUsage": "",
|
||||
"memoryUsage": ""
|
||||
"name": "Nombre",
|
||||
"state": "Estado",
|
||||
"cpuUsage": "Uso de CPU",
|
||||
"memoryUsage": "Uso de memoria"
|
||||
}
|
||||
},
|
||||
"descendingDefaultSort": {
|
||||
"label": ""
|
||||
"label": "Invertir orden"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"description": "Pour commencer, veuillez selectionner comment vous souhaitez configurer votre instance Homarr.",
|
||||
"action": {
|
||||
"scratch": "Partir de zéro",
|
||||
"importOldmarr": "Importer à partir d'Homarr avant la 1.0"
|
||||
"importOldmarr": "Importer depuis Homarr avant la 1.0"
|
||||
}
|
||||
},
|
||||
"import": {
|
||||
@@ -27,7 +27,7 @@
|
||||
"description": "Configurer le comportement d'importation"
|
||||
},
|
||||
"boardSelection": {
|
||||
"title": "{count} tableaux trouvés",
|
||||
"title": "Tableaux {count} trouvés",
|
||||
"description": "Choisissez tous les tableaux avec la taille que vous souhaitez importer",
|
||||
"action": {
|
||||
"selectAll": "Tout sélectionner",
|
||||
@@ -113,7 +113,7 @@
|
||||
"subtitle": "Bon retour parmi nous ! Veuillez entrer vos identifiants"
|
||||
},
|
||||
"invite": {
|
||||
"title": "Rejoindre Homarr",
|
||||
"title": "Rejoignez Homarr",
|
||||
"subtitle": "Bienvenue sur Homarr! Veuillez créer votre compte",
|
||||
"description": "Vous avez été invité par {username}"
|
||||
},
|
||||
@@ -649,14 +649,14 @@
|
||||
"app": {
|
||||
"option": {
|
||||
"existing": {
|
||||
"title": "",
|
||||
"label": ""
|
||||
"title": "Existant",
|
||||
"label": "Sélectionner une application existante"
|
||||
},
|
||||
"new": {
|
||||
"title": "",
|
||||
"title": "Nouveau",
|
||||
"url": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Lien de l'application",
|
||||
"description": "Lien d'ouverture de l'application depuis le tableau de bord"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -676,9 +676,9 @@
|
||||
},
|
||||
"app": {
|
||||
"action": {
|
||||
"add": "",
|
||||
"remove": "",
|
||||
"select": ""
|
||||
"add": "Lier une application",
|
||||
"remove": "Délier",
|
||||
"select": "Sélectionnez une application à lier"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -709,7 +709,7 @@
|
||||
"description": "L'intégration \"{kind}\" peut être utilisée avec les moteurs de recherche. Cochez ceci pour configurer automatiquement le moteur de recherche."
|
||||
},
|
||||
"app": {
|
||||
"sectionTitle": ""
|
||||
"sectionTitle": "Application liée"
|
||||
},
|
||||
"createApp": {
|
||||
"label": "Créer une application",
|
||||
@@ -991,8 +991,8 @@
|
||||
"newLabel": "Nouvel ID d'installation"
|
||||
},
|
||||
"privateKey": {
|
||||
"label": "",
|
||||
"newLabel": ""
|
||||
"label": "Clé privée",
|
||||
"newLabel": "Nouvelle clé privée"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1044,14 +1044,14 @@
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"success": "",
|
||||
"success": "Succès",
|
||||
"beta": "Bêta",
|
||||
"error": "Erreur",
|
||||
"action": {
|
||||
"add": "Ajouter",
|
||||
"apply": "Appliquer",
|
||||
"backToOverview": "Retourner à l'aperçu",
|
||||
"change": "",
|
||||
"change": "Modifier",
|
||||
"create": "Créer",
|
||||
"createAnother": "Créer et recommencer",
|
||||
"edit": "Modifier",
|
||||
@@ -1174,8 +1174,8 @@
|
||||
},
|
||||
"unit": {
|
||||
"speed": {
|
||||
"kilometersPerHour": "",
|
||||
"milesPerHour": ""
|
||||
"kilometersPerHour": "km/h",
|
||||
"milesPerHour": "mph"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1190,7 +1190,7 @@
|
||||
"label": "Titre"
|
||||
},
|
||||
"customCssClasses": {
|
||||
"label": ""
|
||||
"label": "Classes Css personnalisées"
|
||||
},
|
||||
"borderColor": {
|
||||
"label": "Couleur de la bordure"
|
||||
@@ -1321,21 +1321,21 @@
|
||||
"label": "Activer la vérification du statut"
|
||||
},
|
||||
"layout": {
|
||||
"label": "",
|
||||
"label": "Mise en page",
|
||||
"option": {
|
||||
"row": "",
|
||||
"row-reverse": "",
|
||||
"column": "",
|
||||
"column-reverse": ""
|
||||
"row": "Horizontale",
|
||||
"row-reverse": "Horizontal (inversé)",
|
||||
"column": "Vertical",
|
||||
"column-reverse": "Vertical (inversé)"
|
||||
}
|
||||
},
|
||||
"descriptionDisplayMode": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"label": "Mode d'affichage de la description",
|
||||
"description": "Choisissez comment afficher la description de l'application",
|
||||
"option": {
|
||||
"normal": "",
|
||||
"tooltip": "",
|
||||
"hidden": ""
|
||||
"normal": "Au sein du widget",
|
||||
"tooltip": "Comme infobulle",
|
||||
"hidden": "Masquer"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1584,11 +1584,11 @@
|
||||
},
|
||||
"placeholder": "Commencer à écrire vos notes",
|
||||
"dismiss": {
|
||||
"title": "",
|
||||
"message": "",
|
||||
"title": "Abandonner les modifications ?",
|
||||
"message": "Vous avez des modifications non enregistrées dans votre bloc-notes. Êtes-vous sûr de vouloir les supprimer ?",
|
||||
"action": {
|
||||
"discard": "",
|
||||
"keepEditing": ""
|
||||
"discard": "Ignorer les modifications",
|
||||
"keepEditing": "Continuer les modifications"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1743,7 +1743,7 @@
|
||||
"name": "Calendrier",
|
||||
"description": "Afficher les événements de vos intégrations dans une vue calendrier pendant une certaine période de temps relative",
|
||||
"duration": {
|
||||
"allDay": ""
|
||||
"allDay": "Tous les jours"
|
||||
},
|
||||
"option": {
|
||||
"releaseType": {
|
||||
@@ -1780,7 +1780,7 @@
|
||||
"description": "Uniquement sur la météo actuelle"
|
||||
},
|
||||
"useImperialSpeed": {
|
||||
"label": ""
|
||||
"label": "Utiliser mph pour la vitesse du vent"
|
||||
},
|
||||
"location": {
|
||||
"label": "Lieu de la météo"
|
||||
@@ -1941,19 +1941,19 @@
|
||||
"description": "Statistiques de vos conteneurs (Ce widget ne peut être ajouté qu'avec les privilèges d'administrateur)",
|
||||
"option": {
|
||||
"enableRowSorting": {
|
||||
"label": ""
|
||||
"label": "Activer le tri des éléments"
|
||||
},
|
||||
"defaultSort": {
|
||||
"label": "",
|
||||
"label": "Colonne de tri par défaut",
|
||||
"option": {
|
||||
"name": "",
|
||||
"state": "",
|
||||
"cpuUsage": "",
|
||||
"memoryUsage": ""
|
||||
"name": "Nom",
|
||||
"state": "État",
|
||||
"cpuUsage": "Utilisation du CPU",
|
||||
"memoryUsage": "Utilisation mémoire"
|
||||
}
|
||||
},
|
||||
"descendingDefaultSort": {
|
||||
"label": ""
|
||||
"label": "Inverser le tri"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
@@ -2036,21 +2036,21 @@
|
||||
"name": "Nom",
|
||||
"id": "Id",
|
||||
"metadata": {
|
||||
"title": "",
|
||||
"title": "Statistiques détaillées",
|
||||
"video": {
|
||||
"title": "",
|
||||
"resolution": ""
|
||||
"title": "Vidéo",
|
||||
"resolution": "Résolution"
|
||||
},
|
||||
"audio": {
|
||||
"title": "",
|
||||
"channelCount": "",
|
||||
"codec": ""
|
||||
"title": "Audio",
|
||||
"channelCount": "Canaux audio",
|
||||
"codec": "Codec audio"
|
||||
},
|
||||
"transcoding": {
|
||||
"title": "",
|
||||
"container": "",
|
||||
"title": "Transcodage",
|
||||
"container": "Conteneur",
|
||||
"resolution": "Résolution",
|
||||
"target": ""
|
||||
"target": "Codec cible"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2248,7 +2248,7 @@
|
||||
"unknown": "Inconnu",
|
||||
"pending": "En attente",
|
||||
"processing": "Traitement en cours",
|
||||
"requested": "",
|
||||
"requested": "En attente",
|
||||
"partiallyAvailable": "Partiel",
|
||||
"available": "Disponible",
|
||||
"blacklisted": "Sur la liste noire",
|
||||
@@ -2361,7 +2361,7 @@
|
||||
"label": "Nombre maximum de publications"
|
||||
},
|
||||
"hideDescription": {
|
||||
"label": ""
|
||||
"label": "Masquer la description"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2542,7 +2542,7 @@
|
||||
},
|
||||
"firewall": {
|
||||
"name": "Surveillance du pare-feu",
|
||||
"description": "",
|
||||
"description": "Affiche un résumé des pare-feu",
|
||||
"tab": {
|
||||
"system": "Système",
|
||||
"interfaces": "Interfaces"
|
||||
@@ -2556,16 +2556,16 @@
|
||||
"widget": {
|
||||
"fwname": "Nom",
|
||||
"version": "Version",
|
||||
"versiontitle": "",
|
||||
"cputitle": "",
|
||||
"memorytitle": "",
|
||||
"cpu": "",
|
||||
"memory": "",
|
||||
"versiontitle": "Versions",
|
||||
"cputitle": "Utilisation du CPU",
|
||||
"memorytitle": "Utilisation de la mémoire",
|
||||
"cpu": "CPU",
|
||||
"memory": "Mémoire",
|
||||
"interfaces": {
|
||||
"name": "",
|
||||
"trans": "",
|
||||
"recv": "",
|
||||
"title": ""
|
||||
"name": "nom",
|
||||
"trans": "Transmis",
|
||||
"recv": "Reçus",
|
||||
"title": "Interfaces réseau"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2576,37 +2576,37 @@
|
||||
"option": {}
|
||||
},
|
||||
"systemResources": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "Ressources du système",
|
||||
"description": "CPU, Mémoire, Disque et autre utilisation matérielle de votre système",
|
||||
"option": {
|
||||
"hasShadow": {
|
||||
"label": ""
|
||||
"label": "Activer l'ombrage des cartes"
|
||||
},
|
||||
"visibleCharts": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"label": "Graphiques visibles",
|
||||
"description": "Sélectionnez les graphiques à afficher.",
|
||||
"option": {
|
||||
"cpu": "",
|
||||
"memory": "",
|
||||
"network": ""
|
||||
"cpu": "CPU",
|
||||
"memory": "Mémoire",
|
||||
"network": "Réseau"
|
||||
}
|
||||
},
|
||||
"labelDisplayMode": {
|
||||
"label": "",
|
||||
"label": "Mode d'affichage de l'étiquette",
|
||||
"option": {
|
||||
"textWithIcon": "",
|
||||
"text": "",
|
||||
"icon": "",
|
||||
"hidden": ""
|
||||
"textWithIcon": "Afficher le texte avec l'icône",
|
||||
"text": "Afficher uniquement le texte",
|
||||
"icon": "Afficher uniquement l'icône",
|
||||
"hidden": "Masquer l'étiquette"
|
||||
}
|
||||
}
|
||||
},
|
||||
"card": {
|
||||
"cpu": "",
|
||||
"memory": "",
|
||||
"network": "",
|
||||
"up": "",
|
||||
"down": ""
|
||||
"cpu": "CPU",
|
||||
"memory": "RAM",
|
||||
"network": "NET",
|
||||
"up": "UP",
|
||||
"down": "HORS SERVICE"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3030,8 +3030,8 @@
|
||||
"integration": "Intégrations",
|
||||
"app": "Applications",
|
||||
"group": "Groupes",
|
||||
"searchEngine": "",
|
||||
"media": ""
|
||||
"searchEngine": "Moteurs de recherche",
|
||||
"media": "Médias"
|
||||
},
|
||||
"statisticLabel": {
|
||||
"boards": "Tableaux de bord",
|
||||
@@ -3040,8 +3040,8 @@
|
||||
"authorization": "Autorisation"
|
||||
},
|
||||
"heroBanner": {
|
||||
"title": "",
|
||||
"subtitle": ""
|
||||
"title": "Bienvenue sur votre",
|
||||
"subtitle": "Tableau {app}"
|
||||
}
|
||||
},
|
||||
"board": {
|
||||
@@ -3387,19 +3387,19 @@
|
||||
"label": "Conteneurs Docker"
|
||||
},
|
||||
"firewallCpu": {
|
||||
"label": ""
|
||||
"label": "Processeur du pare-feu"
|
||||
},
|
||||
"firewallMemory": {
|
||||
"label": ""
|
||||
"label": "Mémoire du pare-feu"
|
||||
},
|
||||
"firewallVersion": {
|
||||
"label": ""
|
||||
"label": "Version du pare-feu"
|
||||
},
|
||||
"firewallInterfaces": {
|
||||
"label": ""
|
||||
"label": "Interfaces du pare-feu"
|
||||
},
|
||||
"weather": {
|
||||
"label": ""
|
||||
"label": "Météo"
|
||||
}
|
||||
},
|
||||
"interval": {
|
||||
@@ -3410,10 +3410,10 @@
|
||||
"weeklyMonday": "Chaque semaine le lundi",
|
||||
"update": {
|
||||
"success": {
|
||||
"message": ""
|
||||
"message": "Intervalle mis à jour avec succès"
|
||||
},
|
||||
"error": {
|
||||
"message": ""
|
||||
"message": "L'intervalle de mise à jour a échoué"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3422,55 +3422,55 @@
|
||||
},
|
||||
"field": {
|
||||
"name": {
|
||||
"label": ""
|
||||
"label": "Nom"
|
||||
},
|
||||
"interval": {
|
||||
"label": "Intervalle de planification"
|
||||
},
|
||||
"lastExecution": {
|
||||
"label": ""
|
||||
"label": "Dernière exécution"
|
||||
},
|
||||
"actions": {
|
||||
"label": ""
|
||||
"label": "Actions"
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"search": ""
|
||||
"search": "Rechercher des tâches {count}..."
|
||||
},
|
||||
"action": {
|
||||
"refresh": {
|
||||
"label": ""
|
||||
"label": "Rafraîchir"
|
||||
}
|
||||
},
|
||||
"refresh": {
|
||||
"success": {
|
||||
"message": ""
|
||||
"message": "Tâches actualisées avec succès"
|
||||
},
|
||||
"error": {
|
||||
"message": ""
|
||||
"message": "Échec de l'actualisation des tâches"
|
||||
}
|
||||
},
|
||||
"trigger": {
|
||||
"success": {
|
||||
"message": ""
|
||||
"message": "Tâche déclenchée avec succès"
|
||||
},
|
||||
"error": {
|
||||
"message": ""
|
||||
"message": "Échec du déclenchement de la tâche"
|
||||
}
|
||||
},
|
||||
"enable": {
|
||||
"success": {
|
||||
"message": ""
|
||||
"message": "Tâche activée avec succès"
|
||||
}
|
||||
},
|
||||
"disable": {
|
||||
"success": {
|
||||
"message": ""
|
||||
"message": "Tâche désactivée avec succès"
|
||||
}
|
||||
},
|
||||
"toggle": {
|
||||
"error": {
|
||||
"message": ""
|
||||
"message": "Impossible de basculer le statut de la tâche"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3527,19 +3527,19 @@
|
||||
"subtitle": "{count} utilisés dans le Code d'Homarr"
|
||||
},
|
||||
"hotkeys": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"title": "Raccourcis clavier",
|
||||
"subtitle": "Raccourcis clavier pour améliorer votre flux de travail",
|
||||
"field": {
|
||||
"shortcut": "",
|
||||
"action": ""
|
||||
"shortcut": "Raccourci",
|
||||
"action": "Action"
|
||||
},
|
||||
"action": {
|
||||
"toggleBoardEdit": "",
|
||||
"toggleColorScheme": "",
|
||||
"saveNotebook": "",
|
||||
"openSpotlight": ""
|
||||
"toggleBoardEdit": "Activer/désactiver le mode d'édition du tableau",
|
||||
"toggleColorScheme": "Basculer en mode clair/sombre",
|
||||
"saveNotebook": "Enregistrer le bloc-notes (uniquement à l'intérieur du widget notebook)",
|
||||
"openSpotlight": "Ouvrir la recherche"
|
||||
},
|
||||
"note": ""
|
||||
"note": "Astuce : Mod correspond à la touche Ctrl ou ⌘ sur macOS"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3995,7 +3995,7 @@
|
||||
"tools": {
|
||||
"label": "Outils",
|
||||
"tasks": {
|
||||
"label": ""
|
||||
"label": "Tâches"
|
||||
},
|
||||
"docker": {
|
||||
"label": "Docker"
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -177,8 +177,8 @@
|
||||
}
|
||||
},
|
||||
"forgotPassword": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Ste pozabili geslo?",
|
||||
"description": "Administrator lahko zažene ukaz:"
|
||||
}
|
||||
},
|
||||
"register": {
|
||||
@@ -622,7 +622,7 @@
|
||||
"description": "",
|
||||
"action": ""
|
||||
},
|
||||
"add": ""
|
||||
"add": "Dodaj aplikacijo"
|
||||
}
|
||||
},
|
||||
"integration": {
|
||||
@@ -1059,10 +1059,10 @@
|
||||
"insert": "Vstavite",
|
||||
"remove": "Odstrani",
|
||||
"save": "Shrani",
|
||||
"saveChanges": "Shranjevanje sprememb",
|
||||
"saveChanges": "Shrani spremembe",
|
||||
"cancel": "Prekliči",
|
||||
"delete": "Izbriši",
|
||||
"discard": "",
|
||||
"discard": "Zapusti",
|
||||
"close": "",
|
||||
"confirm": "Potrdi",
|
||||
"continue": "",
|
||||
@@ -1125,13 +1125,13 @@
|
||||
"userAvatar": {
|
||||
"menu": {
|
||||
"switchToDarkMode": "",
|
||||
"switchToLightMode": "",
|
||||
"management": "",
|
||||
"preferences": "Vaše želje",
|
||||
"logout": "",
|
||||
"switchToLightMode": "Svetli način",
|
||||
"management": "Nastavitve",
|
||||
"preferences": "Prilagoditev",
|
||||
"logout": "Odjava",
|
||||
"login": "Prijava",
|
||||
"homeBoard": "",
|
||||
"loggedOut": "",
|
||||
"homeBoard": "Vaša nadzorna plošča",
|
||||
"loggedOut": "Odjava uspešna",
|
||||
"updateAvailable": ""
|
||||
}
|
||||
},
|
||||
@@ -1182,7 +1182,7 @@
|
||||
"section": {
|
||||
"dynamic": {
|
||||
"action": {
|
||||
"create": "",
|
||||
"create": "Nova dinamična vsebina",
|
||||
"remove": ""
|
||||
},
|
||||
"option": {
|
||||
@@ -1208,7 +1208,7 @@
|
||||
}
|
||||
},
|
||||
"action": {
|
||||
"create": "",
|
||||
"create": "Nova kategorija",
|
||||
"edit": "",
|
||||
"remove": "",
|
||||
"moveUp": "Premaknite se navzgor",
|
||||
@@ -1243,12 +1243,12 @@
|
||||
},
|
||||
"item": {
|
||||
"action": {
|
||||
"create": "",
|
||||
"create": "Nova vsebina",
|
||||
"import": "",
|
||||
"edit": "",
|
||||
"moveResize": "",
|
||||
"duplicate": "",
|
||||
"remove": ""
|
||||
"edit": "Uredi gradnik",
|
||||
"moveResize": "Premakni/spremeni",
|
||||
"duplicate": "Podvoji",
|
||||
"remove": "Izbriši"
|
||||
},
|
||||
"menu": {
|
||||
"label": {
|
||||
@@ -2638,8 +2638,8 @@
|
||||
"edit": {
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Spremembe so uveljavljene",
|
||||
"message": "Vsebina je bila uspšeno shranjena"
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
@@ -2647,8 +2647,8 @@
|
||||
}
|
||||
},
|
||||
"confirmLeave": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Neshranjene spremembe",
|
||||
"message": "Vsebina ni shranjena, želite nadaljevati?"
|
||||
}
|
||||
},
|
||||
"oldImport": {
|
||||
@@ -2716,16 +2716,16 @@
|
||||
},
|
||||
"field": {
|
||||
"pageTitle": {
|
||||
"label": ""
|
||||
"label": "Naslov strani"
|
||||
},
|
||||
"metaTitle": {
|
||||
"label": ""
|
||||
"label": "Meta naslov"
|
||||
},
|
||||
"logoImageUrl": {
|
||||
"label": ""
|
||||
"label": "URL logotipa"
|
||||
},
|
||||
"faviconImageUrl": {
|
||||
"label": ""
|
||||
"label": "URL ikone"
|
||||
},
|
||||
"backgroundImageUrl": {
|
||||
"label": "",
|
||||
@@ -2835,7 +2835,7 @@
|
||||
"metaTitle": ""
|
||||
},
|
||||
"setting": {
|
||||
"title": "",
|
||||
"title": "Nastavitve za {boardName} nadzorno ploščo",
|
||||
"section": {
|
||||
"general": {
|
||||
"title": "Splošno",
|
||||
@@ -2844,9 +2844,9 @@
|
||||
"layout": {
|
||||
"title": "Postavitev",
|
||||
"responsive": {
|
||||
"title": "",
|
||||
"title": "Predloga",
|
||||
"action": {
|
||||
"add": ""
|
||||
"add": "Dodaj predlogo"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2959,14 +2959,14 @@
|
||||
"layout": {
|
||||
"field": {
|
||||
"name": {
|
||||
"label": ""
|
||||
"label": "Ime"
|
||||
},
|
||||
"columnCount": {
|
||||
"label": ""
|
||||
"label": "Število stolpcev"
|
||||
},
|
||||
"breakpoint": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Prekinitvene točke",
|
||||
"description": "Postavitev bo uporabljena na vseh zaslonih, večjih od te prelomne točke, do naslednje večje prelomne točke."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4046,7 +4046,7 @@
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"placeholder": "Iskanje vsebine",
|
||||
"nothingFound": "",
|
||||
"error": {
|
||||
"fetch": ""
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"@mantine/hooks": "^8.3.10",
|
||||
"@tabler/icons-react": "^3.35.0",
|
||||
"mantine-react-table": "2.0.0-beta.9",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"svgson": "^5.3.1"
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"dayjs": "^1.11.19",
|
||||
"mantine-form-zod-resolver": "^1.3.0",
|
||||
"mantine-react-table": "2.0.0-beta.9",
|
||||
"next": "16.1.0",
|
||||
"next": "16.1.1",
|
||||
"react": "19.2.3",
|
||||
"react-dom": "19.2.3",
|
||||
"react-markdown": "^10.1.0",
|
||||
|
||||
@@ -47,7 +47,7 @@ export const SystemResourceMemoryChart = ({
|
||||
return (
|
||||
<Paper px={3} py={2} withBorder shadow="md" radius="md">
|
||||
<Text c="dimmed" size="xs">
|
||||
{humanFileSize(value)} / {humanFileSize(totalCapacityInBytes)} (
|
||||
{humanFileSize(Math.round(value))} / {humanFileSize(totalCapacityInBytes)} (
|
||||
{Math.round((value / totalCapacityInBytes) * 100)}%)
|
||||
</Text>
|
||||
</Paper>
|
||||
|
||||
@@ -22,6 +22,7 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
|
||||
});
|
||||
const memoryCapacityInBytes =
|
||||
(data[0]?.healthInfo.memAvailableInBytes ?? 0) + (data[0]?.healthInfo.memUsedInBytes ?? 0);
|
||||
|
||||
const [items, setItems] = useState<{ cpu: number; memory: number; network: { up: number; down: number } | null }[]>(
|
||||
data.map((item) => ({
|
||||
cpu: item.healthInfo.cpuUtilization,
|
||||
|
||||
@@ -14,7 +14,7 @@ const labelDisplayModeOptions = {
|
||||
|
||||
export const { definition, componentLoader } = createWidgetDefinition("systemResources", {
|
||||
icon: IconGraphFilled,
|
||||
supportedIntegrations: ["dashDot", "openmediavault", "truenas"],
|
||||
supportedIntegrations: ["dashDot", "openmediavault", "truenas", "unraid"],
|
||||
createOptions() {
|
||||
return optionsBuilder.from((factory) => ({
|
||||
hasShadow: factory.switch({ defaultValue: true }),
|
||||
|
||||
Generated
+471
-475
File diff suppressed because it is too large.
Load diff
@@ -1 +1 @@
|
||||
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"tancak","avatar_url":"https://avatars.githubusercontent.com/u/11760749?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"alotlikebeans","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontent.com/uLine truncated
|
||||
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"tancak","avatar_url":"https://avatars.githubusercontent.com/u/11760749?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"alotlikebeans","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontent.com/uLine truncated
|
||||
@@ -1 +1 @@
|
||||
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/249b02e3368752cb175446082015737c_default.png"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"marinkaberg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14861042/medium/2d5c4e62613f03082f3e645fa92efd59.jpeg"},{"username":"djismgaming","avatarUrl":"httpsLine truncated
|
||||
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/249b02e3368752cb175446082015737c_default.png"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"marinkaberg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14861042/medium/2d5c4e62613f03082f3e645fa92efd59.jpeg"},{"username":"djismgaming","avatarUrl":"httpsLine truncated
|
||||
@@ -17,14 +17,14 @@
|
||||
},
|
||||
"prettier": "@homarr/prettier-config",
|
||||
"dependencies": {
|
||||
"@next/eslint-plugin-next": "16.1.0",
|
||||
"@next/eslint-plugin-next": "16.1.1",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-config-turbo": "^2.7.1",
|
||||
"eslint-config-turbo": "^2.7.2",
|
||||
"eslint-plugin-import": "^2.32.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.10.2",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^6.1.1",
|
||||
"typescript-eslint": "^8.50.0"
|
||||
"typescript-eslint": "^8.50.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||
|
||||
Reference in new issue
Block a user