chore(release): automatic release v1.49.0

This commit is contained in:
homarr-releases[bot] authored and GitHub committed 2026-01-02 19:13:35 +00:00
commit a853463ade
38 files changed
+1537 -966

No files matched your search

+7 -7
View File
@@ -56,16 +56,16 @@
"@mantine/tiptap": "^8.3.10", "@mantine/tiptap": "^8.3.10",
"@million/lint": "1.0.14", "@million/lint": "1.0.14",
"@tabler/icons-react": "^3.35.0", "@tabler/icons-react": "^3.35.0",
"@tanstack/react-query": "^5.90.12", "@tanstack/react-query": "^5.90.14",
"@tanstack/react-query-devtools": "^5.91.1", "@tanstack/react-query-devtools": "^5.91.2",
"@tanstack/react-query-next-experimental": "^5.91.0", "@tanstack/react-query-next-experimental": "^5.91.0",
"@trpc/client": "^11.8.1", "@trpc/client": "^11.8.1",
"@trpc/next": "^11.8.1", "@trpc/next": "^11.8.1",
"@trpc/react-query": "^11.8.1", "@trpc/react-query": "^11.8.1",
"@trpc/server": "^11.8.1", "@trpc/server": "^11.8.1",
"@xterm/addon-canvas": "^0.7.0", "@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "0.10.0", "@xterm/addon-fit": "0.11.0",
"@xterm/xterm": "^5.5.0", "@xterm/xterm": "^6.0.0",
"babel-plugin-react-compiler": "^1.0.0", "babel-plugin-react-compiler": "^1.0.0",
"chroma-js": "^3.2.0", "chroma-js": "^3.2.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
@@ -73,10 +73,10 @@
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"flag-icons": "^7.5.0", "flag-icons": "^7.5.0",
"glob": "^13.0.0", "glob": "^13.0.0",
"isomorphic-dompurify": "^2.34.0", "isomorphic-dompurify": "^2.35.0",
"jotai": "^2.16.0", "jotai": "^2.16.1",
"mantine-react-table": "2.0.0-beta.9", "mantine-react-table": "2.0.0-beta.9",
"next": "16.1.0", "next": "16.1.1",
"postcss-preset-mantine": "^1.18.0", "postcss-preset-mantine": "^1.18.0",
"prismjs": "^1.30.0", "prismjs": "^1.30.0",
"react": "19.2.3", "react": "19.2.3",
@@ -76,6 +76,7 @@ const createColumns = (
accessorKey: "ports", accessorKey: "ports",
header: t("docker.field.ports.label"), header: t("docker.field.ports.label"),
Cell({ cell }) { Cell({ cell }) {
if (!cell.row.original.ports.length) return null;
return ( return (
<OverflowBadge overflowCount={1} data={cell.row.original.ports.map((port) => port.PrivatePort.toString())} /> <OverflowBadge overflowCount={1} data={cell.row.original.ports.map((port) => port.PrivatePort.toString())} />
); );
+1 -1
View File
@@ -49,7 +49,7 @@
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/node": "^24.10.4", "@types/node": "^24.10.4",
"dotenv-cli": "^11.0.0", "dotenv-cli": "^11.0.0",
"esbuild": "^0.27.1", "esbuild": "^0.27.2",
"eslint": "^9.39.2", "eslint": "^9.39.2",
"prettier": "^3.7.4", "prettier": "^3.7.4",
"tsx": "4.20.4", "tsx": "4.20.4",
+1 -1
View File
@@ -34,7 +34,7 @@
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"@types/ws": "^8.18.1", "@types/ws": "^8.18.1",
"esbuild": "^0.27.1", "esbuild": "^0.27.2",
"eslint": "^9.39.2", "eslint": "^9.39.2",
"prettier": "^3.7.4", "prettier": "^3.7.4",
"typescript": "^5.9.3" "typescript": "^5.9.3"
+2 -2
View File
@@ -4,10 +4,10 @@
"dependencies": { "dependencies": {
"better-sqlite3": "^12.5.0" "better-sqlite3": "^12.5.0"
}, },
"packageManager": "pnpm@10.26.1", "packageManager": "pnpm@10.26.2",
"engines": { "engines": {
"node": ">=24.12.0", "node": ">=24.12.0",
"pnpm": ">=10.26.1" "pnpm": ">=10.26.2"
}, },
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
+7
View File
@@ -314,6 +314,13 @@
<br/> <br/>
<p align="center">Unifi<br/>Controller</p> <p align="center">Unifi<br/>Controller</p>
</a> </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> </td></tr>
</tbody> </tbody>
</table> </table>
+10 -10
View File
@@ -42,27 +42,27 @@
"@semantic-release/github": "^12.0.2", "@semantic-release/github": "^12.0.2",
"@semantic-release/npm": "^13.1.3", "@semantic-release/npm": "^13.1.3",
"@semantic-release/release-notes-generator": "^14.1.0", "@semantic-release/release-notes-generator": "^14.1.0",
"@testcontainers/redis": "^11.10.0", "@testcontainers/redis": "^11.11.0",
"@turbo/gen": "^2.7.1", "@turbo/gen": "^2.7.2",
"@vitejs/plugin-react": "^5.1.2", "@vitejs/plugin-react": "^5.1.2",
"@vitest/coverage-v8": "^4.0.16", "@vitest/coverage-v8": "^4.0.16",
"@vitest/ui": "^4.0.16", "@vitest/ui": "^4.0.16",
"conventional-changelog-conventionalcommits": "^9.1.0", "conventional-changelog-conventionalcommits": "^9.1.0",
"cross-env": "^10.1.0", "cross-env": "^10.1.0",
"jsdom": "^27.3.0", "jsdom": "^27.4.0",
"json5": "^2.2.3", "json5": "^2.2.3",
"prettier": "^3.7.4", "prettier": "^3.7.4",
"semantic-release": "^25.0.2", "semantic-release": "^25.0.2",
"testcontainers": "^11.10.0", "testcontainers": "^11.11.0",
"turbo": "^2.7.1", "turbo": "^2.7.2",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"vite-tsconfig-paths": "^5.1.4", "vite-tsconfig-paths": "^6.0.3",
"vitest": "^4.0.16" "vitest": "^4.0.16"
}, },
"packageManager": "pnpm@10.26.1", "packageManager": "pnpm@10.26.2",
"engines": { "engines": {
"node": ">=24.12.0", "node": ">=24.12.0",
"pnpm": ">=10.26.1" "pnpm": ">=10.26.2"
}, },
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
@@ -82,9 +82,9 @@
"axios@>=1.0.0 <1.8.2": ">=1.13.2", "axios@>=1.0.0 <1.8.2": ">=1.13.2",
"brace-expansion@>=2.0.0 <=2.0.1": ">=4.0.1", "brace-expansion@>=2.0.0 <=2.0.1": ">=4.0.1",
"brace-expansion@>=1.0.0 <=1.1.11": ">=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", "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", "linkifyjs@<4.3.2": ">=4.3.2",
"nanoid@>=4.0.0 <5.0.9": ">=5.1.6", "nanoid@>=4.0.0 <5.0.9": ">=5.1.6",
"prismjs@<1.30.0": ">=1.30.0", "prismjs@<1.30.0": ">=1.30.0",
+2 -2
View File
@@ -41,13 +41,13 @@
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@kubernetes/client-node": "^1.4.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/client": "^11.8.1",
"@trpc/react-query": "^11.8.1", "@trpc/react-query": "^11.8.1",
"@trpc/server": "^11.8.1", "@trpc/server": "^11.8.1",
"@trpc/tanstack-react-query": "^11.8.1", "@trpc/tanstack-react-query": "^11.8.1",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
"next": "16.1.0", "next": "16.1.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"superjson": "2.2.6", "superjson": "2.2.6",
@@ -9,7 +9,7 @@ import { createTRPCRouter, publicProcedure } from "../../trpc";
export const healthMonitoringRouter = createTRPCRouter({ export const healthMonitoringRouter = createTRPCRouter({
getSystemHealthStatus: publicProcedure getSystemHealthStatus: publicProcedure
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "mock")) .concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "unraid", "mock"))
.query(async ({ ctx }) => { .query(async ({ ctx }) => {
return await Promise.all( return await Promise.all(
ctx.integrations.map(async (integration) => { ctx.integrations.map(async (integration) => {
@@ -26,7 +26,7 @@ export const healthMonitoringRouter = createTRPCRouter({
); );
}), }),
subscribeSystemHealthStatus: publicProcedure subscribeSystemHealthStatus: publicProcedure
.concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "mock")) .concat(createManyIntegrationMiddleware("query", "openmediavault", "dashDot", "truenas", "unraid", "mock"))
.subscription(({ ctx }) => { .subscription(({ ctx }) => {
return observable<{ integrationId: string; healthInfo: SystemHealthMonitoring; timestamp: Date }>((emit) => { return observable<{ integrationId: string; healthInfo: SystemHealthMonitoring; timestamp: Date }>((emit) => {
const unsubscribes: (() => void)[] = []; const unsubscribes: (() => void)[] = [];
+2 -2
View File
@@ -32,8 +32,8 @@
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"bcrypt": "^6.0.0", "bcrypt": "^6.0.0",
"cookies": "^0.9.1", "cookies": "^0.9.1",
"ldapts": "8.0.30", "ldapts": "8.0.35",
"next": "16.1.0", "next": "16.1.1",
"next-auth": "5.0.0-beta.30", "next-auth": "5.0.0-beta.30",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
+1 -1
View File
@@ -34,7 +34,7 @@
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"esbuild": "^0.27.1", "esbuild": "^0.27.2",
"eslint": "^9.39.2", "eslint": "^9.39.2",
"typescript": "^5.9.3" "typescript": "^5.9.3"
} }
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/core": "workspace:^0.1.0", "@homarr/core": "workspace:^0.1.0",
"@paralleldrive/cuid2": "^3.1.0", "@paralleldrive/cuid2": "^3.1.0",
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"next": "16.1.0", "next": "16.1.1",
"octokit": "^5.0.5", "octokit": "^5.0.5",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
+1 -1
View File
@@ -28,7 +28,7 @@
"@homarr/common": "workspace:^0.1.0", "@homarr/common": "workspace:^0.1.0",
"@homarr/core": "workspace:^0.1.0", "@homarr/core": "workspace:^0.1.0",
"@homarr/cron-jobs": "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/client": "^11.8.1",
"@trpc/server": "^11.8.1", "@trpc/server": "^11.8.1",
"@trpc/tanstack-react-query": "^11.8.1", "@trpc/tanstack-react-query": "^11.8.1",
+3 -3
View File
@@ -49,8 +49,8 @@
"@homarr/server-settings": "workspace:^0.1.0", "@homarr/server-settings": "workspace:^0.1.0",
"@mantine/core": "^8.3.10", "@mantine/core": "^8.3.10",
"@paralleldrive/cuid2": "^3.1.0", "@paralleldrive/cuid2": "^3.1.0",
"@testcontainers/mysql": "^11.10.0", "@testcontainers/mysql": "^11.11.0",
"@testcontainers/postgresql": "^11.10.0", "@testcontainers/postgresql": "^11.11.0",
"better-sqlite3": "^12.5.0", "better-sqlite3": "^12.5.0",
"dotenv": "^17.2.3", "dotenv": "^17.2.3",
"drizzle-kit": "^0.31.8", "drizzle-kit": "^0.31.8",
@@ -67,7 +67,7 @@
"@types/better-sqlite3": "7.6.13", "@types/better-sqlite3": "7.6.13",
"@types/pg": "^8.16.0", "@types/pg": "^8.16.0",
"dotenv-cli": "^11.0.0", "dotenv-cli": "^11.0.0",
"esbuild": "^0.27.1", "esbuild": "^0.27.2",
"eslint": "^9.39.2", "eslint": "^9.39.2",
"prettier": "^3.7.4", "prettier": "^3.7.4",
"tsx": "4.20.4", "tsx": "4.20.4",
+7
View File
@@ -298,6 +298,13 @@ export const integrationDefs = {
category: ["healthMonitoring"], category: ["healthMonitoring"],
documentationUrl: createDocumentationLink("/docs/integrations/truenas"), 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) // 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: { mock: {
name: "Mock", name: "Mock",
@@ -38,6 +38,7 @@ import { ProxmoxIntegration } from "../proxmox/proxmox-integration";
import { QuayIntegration } from "../quay/quay-integration"; import { QuayIntegration } from "../quay/quay-integration";
import { TrueNasIntegration } from "../truenas/truenas-integration"; import { TrueNasIntegration } from "../truenas/truenas-integration";
import { UnifiControllerIntegration } from "../unifi-controller/unifi-controller-integration"; import { UnifiControllerIntegration } from "../unifi-controller/unifi-controller-integration";
import { UnraidIntegration } from "../unraid/unraid-integration";
import type { Integration, IntegrationInput } from "./integration"; import type { Integration, IntegrationInput } from "./integration";
export const createIntegrationAsync = async <TKind extends keyof typeof integrationCreators>( export const createIntegrationAsync = async <TKind extends keyof typeof integrationCreators>(
@@ -101,6 +102,7 @@ export const integrationCreators = {
ntfy: NTFYIntegration, ntfy: NTFYIntegration,
mock: MockIntegration, mock: MockIntegration,
truenas: TrueNasIntegration, truenas: TrueNasIntegration,
unraid: UnraidIntegration,
} satisfies Record<IntegrationKind, IntegrationInstance | [(input: IntegrationInput) => Promise<Integration>]>; } satisfies Record<IntegrationKind, IntegrationInstance | [(input: IntegrationInput) => Promise<Integration>]>;
type IntegrationInstanceOfKind<TKind extends keyof typeof integrationCreators> = { type IntegrationInstanceOfKind<TKind extends keyof typeof integrationCreators> = {
+1
View File
@@ -22,6 +22,7 @@ export { PiHoleIntegrationV6 } from "./pi-hole/v6/pi-hole-integration-v6";
export { PlexIntegration } from "./plex/plex-integration"; export { PlexIntegration } from "./plex/plex-integration";
export { ProwlarrIntegration } from "./prowlarr/prowlarr-integration"; export { ProwlarrIntegration } from "./prowlarr/prowlarr-integration";
export { TrueNasIntegration } from "./truenas/truenas-integration"; export { TrueNasIntegration } from "./truenas/truenas-integration";
export { UnraidIntegration } from "./unraid/unraid-integration";
export { OPNsenseIntegration } from "./opnsense/opnsense-integration"; export { OPNsenseIntegration } from "./opnsense/opnsense-integration";
export { ICalIntegration } from "./ical/ical-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,
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(),
}),
),
}),
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>;
+1 -1
View File
@@ -36,7 +36,7 @@
"@mantine/core": "^8.3.10", "@mantine/core": "^8.3.10",
"@tabler/icons-react": "^3.35.0", "@tabler/icons-react": "^3.35.0",
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"next": "16.1.0", "next": "16.1.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"zod": "^4.2.1" "zod": "^4.2.1"
+1 -1
View File
@@ -40,7 +40,7 @@
"@mantine/core": "^8.3.10", "@mantine/core": "^8.3.10",
"@mantine/hooks": "^8.3.10", "@mantine/hooks": "^8.3.10",
"adm-zip": "0.5.16", "adm-zip": "0.5.16",
"next": "16.1.0", "next": "16.1.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"superjson": "2.2.6", "superjson": "2.2.6",
+47 -20
View File
@@ -12,9 +12,7 @@ export const dockerContainersRequestHandler = createCachedWidgetRequestHandler({
queryKey: "dockerContainersResult", queryKey: "dockerContainersResult",
widgetKind: "dockerContainers", widgetKind: "dockerContainers",
async requestAsync() { async requestAsync() {
const containers = await getContainersWithStatsAsync(); return await getContainersWithStatsAsync();
return containers;
}, },
cacheDuration: dayjs.duration(20, "seconds"), cacheDuration: dayjs.duration(20, "seconds"),
}); });
@@ -28,7 +26,7 @@ async function getContainersWithStatsAsync() {
dockerInstances.map(async ({ instance, host }) => { dockerInstances.map(async ({ instance, host }) => {
const instanceContainers = await instance.listContainers({ all: true }); const instanceContainers = await instance.listContainers({ all: true });
return instanceContainers return instanceContainers
.filter((container) => dockerLabels.hide in container.Labels === false) .filter((container) => !(dockerLabels.hide in container.Labels))
.map((container) => ({ ...container, instance: host })); .map((container) => ({ ...container, instance: host }));
}), }),
).then((res) => res.flat()); ).then((res) => res.flat());
@@ -45,7 +43,21 @@ async function getContainersWithStatsAsync() {
const instance = dockerInstances.find(({ host }) => host === container.instance)?.instance; const instance = dockerInstances.find(({ host }) => host === container.instance)?.instance;
if (!instance) return null; 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 { return {
id: container.Id, id: container.Id,
@@ -57,19 +69,8 @@ async function getContainersWithStatsAsync() {
if (!extractedImage) return false; if (!extractedImage) return false;
return icon.name.toLowerCase().includes(extractedImage.toLowerCase()); return icon.name.toLowerCase().includes(extractedImage.toLowerCase());
})?.url ?? null, })?.url ?? null,
cpuUsage: calculateCpuUsage(stats), cpuUsage,
// memory usage by default includes cache, which should not be shown as it is also not shown with docker stats command memoryUsage,
// 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),
image: container.Image, image: container.Image,
ports: container.Ports, ports: container.Ports,
}; };
@@ -79,10 +80,36 @@ async function getContainersWithStatsAsync() {
} }
function calculateCpuUsage(stats: ContainerStats): number { 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; 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; 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)
);
}
+1 -1
View File
@@ -27,7 +27,7 @@
"@homarr/db": "workspace:^0.1.0", "@homarr/db": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0", "@homarr/server-settings": "workspace:^0.1.0",
"@mantine/dates": "^8.3.10", "@mantine/dates": "^8.3.10",
"next": "16.1.0", "next": "16.1.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3" "react-dom": "19.2.3"
}, },
+2 -2
View File
@@ -37,8 +37,8 @@
"@mantine/hooks": "^8.3.10", "@mantine/hooks": "^8.3.10",
"@mantine/spotlight": "^8.3.10", "@mantine/spotlight": "^8.3.10",
"@tabler/icons-react": "^3.35.0", "@tabler/icons-react": "^3.35.0",
"jotai": "^2.16.0", "jotai": "^2.16.1",
"next": "16.1.0", "next": "16.1.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"use-deep-compare-effect": "^1.8.1" "use-deep-compare-effect": "^1.8.1"
+1 -1
View File
@@ -32,7 +32,7 @@
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"deepmerge": "4.3.1", "deepmerge": "4.3.1",
"mantine-react-table": "2.0.0-beta.9", "mantine-react-table": "2.0.0-beta.9",
"next": "16.1.0", "next": "16.1.1",
"next-intl": "4.6.1", "next-intl": "4.6.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3" "react-dom": "19.2.3"
+7 -7
View File
@@ -1941,19 +1941,19 @@
"description": "Estadísticas de tus contenedores (Este widget sólo puede ser añadido con privilegios de administrador)", "description": "Estadísticas de tus contenedores (Este widget sólo puede ser añadido con privilegios de administrador)",
"option": { "option": {
"enableRowSorting": { "enableRowSorting": {
"label": "" "label": "Habilitar ordenar elementos"
}, },
"defaultSort": { "defaultSort": {
"label": "", "label": "Columna usada para ordenar por defecto",
"option": { "option": {
"name": "", "name": "Nombre",
"state": "", "state": "Estado",
"cpuUsage": "", "cpuUsage": "Uso de CPU",
"memoryUsage": "" "memoryUsage": "Uso de memoria"
} }
}, },
"descendingDefaultSort": { "descendingDefaultSort": {
"label": "" "label": "Invertir orden"
} }
}, },
"error": { "error": {
+114 -114
View File
@@ -7,7 +7,7 @@
"description": "Pour commencer, veuillez selectionner comment vous souhaitez configurer votre instance Homarr.", "description": "Pour commencer, veuillez selectionner comment vous souhaitez configurer votre instance Homarr.",
"action": { "action": {
"scratch": "Partir de zéro", "scratch": "Partir de zéro",
"importOldmarr": "Importer à partir d'Homarr avant la 1.0" "importOldmarr": "Importer depuis Homarr avant la 1.0"
} }
}, },
"import": { "import": {
@@ -27,7 +27,7 @@
"description": "Configurer le comportement d'importation" "description": "Configurer le comportement d'importation"
}, },
"boardSelection": { "boardSelection": {
"title": "{count} tableaux trouvés", "title": "Tableaux {count} trouvés",
"description": "Choisissez tous les tableaux avec la taille que vous souhaitez importer", "description": "Choisissez tous les tableaux avec la taille que vous souhaitez importer",
"action": { "action": {
"selectAll": "Tout sélectionner", "selectAll": "Tout sélectionner",
@@ -113,7 +113,7 @@
"subtitle": "Bon retour parmi nous ! Veuillez entrer vos identifiants" "subtitle": "Bon retour parmi nous ! Veuillez entrer vos identifiants"
}, },
"invite": { "invite": {
"title": "Rejoindre Homarr", "title": "Rejoignez Homarr",
"subtitle": "Bienvenue sur Homarr! Veuillez créer votre compte", "subtitle": "Bienvenue sur Homarr! Veuillez créer votre compte",
"description": "Vous avez été invité par {username}" "description": "Vous avez été invité par {username}"
}, },
@@ -649,14 +649,14 @@
"app": { "app": {
"option": { "option": {
"existing": { "existing": {
"title": "", "title": "Existant",
"label": "" "label": "Sélectionner une application existante"
}, },
"new": { "new": {
"title": "", "title": "Nouveau",
"url": { "url": {
"label": "", "label": "Lien de l'application",
"description": "" "description": "Lien d'ouverture de l'application depuis le tableau de bord"
} }
} }
} }
@@ -676,9 +676,9 @@
}, },
"app": { "app": {
"action": { "action": {
"add": "", "add": "Lier une application",
"remove": "", "remove": "Délier",
"select": "" "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." "description": "L'intégration \"{kind}\" peut être utilisée avec les moteurs de recherche. Cochez ceci pour configurer automatiquement le moteur de recherche."
}, },
"app": { "app": {
"sectionTitle": "" "sectionTitle": "Application liée"
}, },
"createApp": { "createApp": {
"label": "Créer une application", "label": "Créer une application",
@@ -991,8 +991,8 @@
"newLabel": "Nouvel ID d'installation" "newLabel": "Nouvel ID d'installation"
}, },
"privateKey": { "privateKey": {
"label": "", "label": "Clé privée",
"newLabel": "" "newLabel": "Nouvelle clé privée"
} }
} }
}, },
@@ -1044,14 +1044,14 @@
} }
}, },
"common": { "common": {
"success": "", "success": "Succès",
"beta": "Bêta", "beta": "Bêta",
"error": "Erreur", "error": "Erreur",
"action": { "action": {
"add": "Ajouter", "add": "Ajouter",
"apply": "Appliquer", "apply": "Appliquer",
"backToOverview": "Retourner à l'aperçu", "backToOverview": "Retourner à l'aperçu",
"change": "", "change": "Modifier",
"create": "Créer", "create": "Créer",
"createAnother": "Créer et recommencer", "createAnother": "Créer et recommencer",
"edit": "Modifier", "edit": "Modifier",
@@ -1174,8 +1174,8 @@
}, },
"unit": { "unit": {
"speed": { "speed": {
"kilometersPerHour": "", "kilometersPerHour": "km/h",
"milesPerHour": "" "milesPerHour": "mph"
} }
} }
}, },
@@ -1190,7 +1190,7 @@
"label": "Titre" "label": "Titre"
}, },
"customCssClasses": { "customCssClasses": {
"label": "" "label": "Classes Css personnalisées"
}, },
"borderColor": { "borderColor": {
"label": "Couleur de la bordure" "label": "Couleur de la bordure"
@@ -1321,21 +1321,21 @@
"label": "Activer la vérification du statut" "label": "Activer la vérification du statut"
}, },
"layout": { "layout": {
"label": "", "label": "Mise en page",
"option": { "option": {
"row": "", "row": "Horizontale",
"row-reverse": "", "row-reverse": "Horizontal (inversé)",
"column": "", "column": "Vertical",
"column-reverse": "" "column-reverse": "Vertical (inversé)"
} }
}, },
"descriptionDisplayMode": { "descriptionDisplayMode": {
"label": "", "label": "Mode d'affichage de la description",
"description": "", "description": "Choisissez comment afficher la description de l'application",
"option": { "option": {
"normal": "", "normal": "Au sein du widget",
"tooltip": "", "tooltip": "Comme infobulle",
"hidden": "" "hidden": "Masquer"
} }
} }
}, },
@@ -1584,11 +1584,11 @@
}, },
"placeholder": "Commencer à écrire vos notes", "placeholder": "Commencer à écrire vos notes",
"dismiss": { "dismiss": {
"title": "", "title": "Abandonner les modifications ?",
"message": "", "message": "Vous avez des modifications non enregistrées dans votre bloc-notes. Êtes-vous sûr de vouloir les supprimer ?",
"action": { "action": {
"discard": "", "discard": "Ignorer les modifications",
"keepEditing": "" "keepEditing": "Continuer les modifications"
} }
} }
}, },
@@ -1743,7 +1743,7 @@
"name": "Calendrier", "name": "Calendrier",
"description": "Afficher les événements de vos intégrations dans une vue calendrier pendant une certaine période de temps relative", "description": "Afficher les événements de vos intégrations dans une vue calendrier pendant une certaine période de temps relative",
"duration": { "duration": {
"allDay": "" "allDay": "Tous les jours"
}, },
"option": { "option": {
"releaseType": { "releaseType": {
@@ -1780,7 +1780,7 @@
"description": "Uniquement sur la météo actuelle" "description": "Uniquement sur la météo actuelle"
}, },
"useImperialSpeed": { "useImperialSpeed": {
"label": "" "label": "Utiliser mph pour la vitesse du vent"
}, },
"location": { "location": {
"label": "Lieu de la météo" "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)", "description": "Statistiques de vos conteneurs (Ce widget ne peut être ajouté qu'avec les privilèges d'administrateur)",
"option": { "option": {
"enableRowSorting": { "enableRowSorting": {
"label": "" "label": "Activer le tri des éléments"
}, },
"defaultSort": { "defaultSort": {
"label": "", "label": "Colonne de tri par défaut",
"option": { "option": {
"name": "", "name": "Nom",
"state": "", "state": "État",
"cpuUsage": "", "cpuUsage": "Utilisation du CPU",
"memoryUsage": "" "memoryUsage": "Utilisation mémoire"
} }
}, },
"descendingDefaultSort": { "descendingDefaultSort": {
"label": "" "label": "Inverser le tri"
} }
}, },
"error": { "error": {
@@ -2036,21 +2036,21 @@
"name": "Nom", "name": "Nom",
"id": "Id", "id": "Id",
"metadata": { "metadata": {
"title": "", "title": "Statistiques détaillées",
"video": { "video": {
"title": "", "title": "Vidéo",
"resolution": "" "resolution": "Résolution"
}, },
"audio": { "audio": {
"title": "", "title": "Audio",
"channelCount": "", "channelCount": "Canaux audio",
"codec": "" "codec": "Codec audio"
}, },
"transcoding": { "transcoding": {
"title": "", "title": "Transcodage",
"container": "", "container": "Conteneur",
"resolution": "Résolution", "resolution": "Résolution",
"target": "" "target": "Codec cible"
} }
} }
} }
@@ -2248,7 +2248,7 @@
"unknown": "Inconnu", "unknown": "Inconnu",
"pending": "En attente", "pending": "En attente",
"processing": "Traitement en cours", "processing": "Traitement en cours",
"requested": "", "requested": "En attente",
"partiallyAvailable": "Partiel", "partiallyAvailable": "Partiel",
"available": "Disponible", "available": "Disponible",
"blacklisted": "Sur la liste noire", "blacklisted": "Sur la liste noire",
@@ -2361,7 +2361,7 @@
"label": "Nombre maximum de publications" "label": "Nombre maximum de publications"
}, },
"hideDescription": { "hideDescription": {
"label": "" "label": "Masquer la description"
} }
} }
}, },
@@ -2542,7 +2542,7 @@
}, },
"firewall": { "firewall": {
"name": "Surveillance du pare-feu", "name": "Surveillance du pare-feu",
"description": "", "description": "Affiche un résumé des pare-feu",
"tab": { "tab": {
"system": "Système", "system": "Système",
"interfaces": "Interfaces" "interfaces": "Interfaces"
@@ -2556,16 +2556,16 @@
"widget": { "widget": {
"fwname": "Nom", "fwname": "Nom",
"version": "Version", "version": "Version",
"versiontitle": "", "versiontitle": "Versions",
"cputitle": "", "cputitle": "Utilisation du CPU",
"memorytitle": "", "memorytitle": "Utilisation de la mémoire",
"cpu": "", "cpu": "CPU",
"memory": "", "memory": "Mémoire",
"interfaces": { "interfaces": {
"name": "", "name": "nom",
"trans": "", "trans": "Transmis",
"recv": "", "recv": "Reçus",
"title": "" "title": "Interfaces réseau"
} }
} }
}, },
@@ -2576,37 +2576,37 @@
"option": {} "option": {}
}, },
"systemResources": { "systemResources": {
"name": "", "name": "Ressources du système",
"description": "", "description": "CPU, Mémoire, Disque et autre utilisation matérielle de votre système",
"option": { "option": {
"hasShadow": { "hasShadow": {
"label": "" "label": "Activer l'ombrage des cartes"
}, },
"visibleCharts": { "visibleCharts": {
"label": "", "label": "Graphiques visibles",
"description": "", "description": "Sélectionnez les graphiques à afficher.",
"option": { "option": {
"cpu": "", "cpu": "CPU",
"memory": "", "memory": "Mémoire",
"network": "" "network": "Réseau"
} }
}, },
"labelDisplayMode": { "labelDisplayMode": {
"label": "", "label": "Mode d'affichage de l'étiquette",
"option": { "option": {
"textWithIcon": "", "textWithIcon": "Afficher le texte avec l'icône",
"text": "", "text": "Afficher uniquement le texte",
"icon": "", "icon": "Afficher uniquement l'icône",
"hidden": "" "hidden": "Masquer l'étiquette"
} }
} }
}, },
"card": { "card": {
"cpu": "", "cpu": "CPU",
"memory": "", "memory": "RAM",
"network": "", "network": "NET",
"up": "", "up": "UP",
"down": "" "down": "HORS SERVICE"
} }
} }
}, },
@@ -3030,8 +3030,8 @@
"integration": "Intégrations", "integration": "Intégrations",
"app": "Applications", "app": "Applications",
"group": "Groupes", "group": "Groupes",
"searchEngine": "", "searchEngine": "Moteurs de recherche",
"media": "" "media": "Médias"
}, },
"statisticLabel": { "statisticLabel": {
"boards": "Tableaux de bord", "boards": "Tableaux de bord",
@@ -3040,8 +3040,8 @@
"authorization": "Autorisation" "authorization": "Autorisation"
}, },
"heroBanner": { "heroBanner": {
"title": "", "title": "Bienvenue sur votre",
"subtitle": "" "subtitle": "Tableau {app}"
} }
}, },
"board": { "board": {
@@ -3387,19 +3387,19 @@
"label": "Conteneurs Docker" "label": "Conteneurs Docker"
}, },
"firewallCpu": { "firewallCpu": {
"label": "" "label": "Processeur du pare-feu"
}, },
"firewallMemory": { "firewallMemory": {
"label": "" "label": "Mémoire du pare-feu"
}, },
"firewallVersion": { "firewallVersion": {
"label": "" "label": "Version du pare-feu"
}, },
"firewallInterfaces": { "firewallInterfaces": {
"label": "" "label": "Interfaces du pare-feu"
}, },
"weather": { "weather": {
"label": "" "label": "Météo"
} }
}, },
"interval": { "interval": {
@@ -3410,10 +3410,10 @@
"weeklyMonday": "Chaque semaine le lundi", "weeklyMonday": "Chaque semaine le lundi",
"update": { "update": {
"success": { "success": {
"message": "" "message": "Intervalle mis à jour avec succès"
}, },
"error": { "error": {
"message": "" "message": "L'intervalle de mise à jour a échoué"
} }
} }
}, },
@@ -3422,55 +3422,55 @@
}, },
"field": { "field": {
"name": { "name": {
"label": "" "label": "Nom"
}, },
"interval": { "interval": {
"label": "Intervalle de planification" "label": "Intervalle de planification"
}, },
"lastExecution": { "lastExecution": {
"label": "" "label": "Dernière exécution"
}, },
"actions": { "actions": {
"label": "" "label": "Actions"
} }
}, },
"table": { "table": {
"search": "" "search": "Rechercher des tâches {count}..."
}, },
"action": { "action": {
"refresh": { "refresh": {
"label": "" "label": "Rafraîchir"
} }
}, },
"refresh": { "refresh": {
"success": { "success": {
"message": "" "message": "Tâches actualisées avec succès"
}, },
"error": { "error": {
"message": "" "message": "Échec de l'actualisation des tâches"
} }
}, },
"trigger": { "trigger": {
"success": { "success": {
"message": "" "message": "Tâche déclenchée avec succès"
}, },
"error": { "error": {
"message": "" "message": "Échec du déclenchement de la tâche"
} }
}, },
"enable": { "enable": {
"success": { "success": {
"message": "" "message": "Tâche activée avec succès"
} }
}, },
"disable": { "disable": {
"success": { "success": {
"message": "" "message": "Tâche désactivée avec succès"
} }
}, },
"toggle": { "toggle": {
"error": { "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" "subtitle": "{count} utilisés dans le Code d'Homarr"
}, },
"hotkeys": { "hotkeys": {
"title": "", "title": "Raccourcis clavier",
"subtitle": "", "subtitle": "Raccourcis clavier pour améliorer votre flux de travail",
"field": { "field": {
"shortcut": "", "shortcut": "Raccourci",
"action": "" "action": "Action"
}, },
"action": { "action": {
"toggleBoardEdit": "", "toggleBoardEdit": "Activer/désactiver le mode d'édition du tableau",
"toggleColorScheme": "", "toggleColorScheme": "Basculer en mode clair/sombre",
"saveNotebook": "", "saveNotebook": "Enregistrer le bloc-notes (uniquement à l'intérieur du widget notebook)",
"openSpotlight": "" "openSpotlight": "Ouvrir la recherche"
}, },
"note": "" "note": "Astuce : Mod correspond à la touche Ctrl ou ⌘ sur macOS"
} }
} }
} }
@@ -3995,7 +3995,7 @@
"tools": { "tools": {
"label": "Outils", "label": "Outils",
"tasks": { "tasks": {
"label": "" "label": "Tâches"
}, },
"docker": { "docker": {
"label": "Docker" "label": "Docker"
File diff suppressed because it is too large. Load diff
+34 -34
View File
@@ -177,8 +177,8 @@
} }
}, },
"forgotPassword": { "forgotPassword": {
"label": "", "label": "Ste pozabili geslo?",
"description": "" "description": "Administrator lahko zažene ukaz:"
} }
}, },
"register": { "register": {
@@ -622,7 +622,7 @@
"description": "", "description": "",
"action": "" "action": ""
}, },
"add": "" "add": "Dodaj aplikacijo"
} }
}, },
"integration": { "integration": {
@@ -1059,10 +1059,10 @@
"insert": "Vstavite", "insert": "Vstavite",
"remove": "Odstrani", "remove": "Odstrani",
"save": "Shrani", "save": "Shrani",
"saveChanges": "Shranjevanje sprememb", "saveChanges": "Shrani spremembe",
"cancel": "Prekliči", "cancel": "Prekliči",
"delete": "Izbriši", "delete": "Izbriši",
"discard": "", "discard": "Zapusti",
"close": "", "close": "",
"confirm": "Potrdi", "confirm": "Potrdi",
"continue": "", "continue": "",
@@ -1125,13 +1125,13 @@
"userAvatar": { "userAvatar": {
"menu": { "menu": {
"switchToDarkMode": "", "switchToDarkMode": "",
"switchToLightMode": "", "switchToLightMode": "Svetli način",
"management": "", "management": "Nastavitve",
"preferences": "Vaše želje", "preferences": "Prilagoditev",
"logout": "", "logout": "Odjava",
"login": "Prijava", "login": "Prijava",
"homeBoard": "", "homeBoard": "Vaša nadzorna plošča",
"loggedOut": "", "loggedOut": "Odjava uspešna",
"updateAvailable": "" "updateAvailable": ""
} }
}, },
@@ -1182,7 +1182,7 @@
"section": { "section": {
"dynamic": { "dynamic": {
"action": { "action": {
"create": "", "create": "Nova dinamična vsebina",
"remove": "" "remove": ""
}, },
"option": { "option": {
@@ -1208,7 +1208,7 @@
} }
}, },
"action": { "action": {
"create": "", "create": "Nova kategorija",
"edit": "", "edit": "",
"remove": "", "remove": "",
"moveUp": "Premaknite se navzgor", "moveUp": "Premaknite se navzgor",
@@ -1243,12 +1243,12 @@
}, },
"item": { "item": {
"action": { "action": {
"create": "", "create": "Nova vsebina",
"import": "", "import": "",
"edit": "", "edit": "Uredi gradnik",
"moveResize": "", "moveResize": "Premakni/spremeni",
"duplicate": "", "duplicate": "Podvoji",
"remove": "" "remove": "Izbriši"
}, },
"menu": { "menu": {
"label": { "label": {
@@ -2638,8 +2638,8 @@
"edit": { "edit": {
"notification": { "notification": {
"success": { "success": {
"title": "", "title": "Spremembe so uveljavljene",
"message": "" "message": "Vsebina je bila uspšeno shranjena"
}, },
"error": { "error": {
"title": "", "title": "",
@@ -2647,8 +2647,8 @@
} }
}, },
"confirmLeave": { "confirmLeave": {
"title": "", "title": "Neshranjene spremembe",
"message": "" "message": "Vsebina ni shranjena, želite nadaljevati?"
} }
}, },
"oldImport": { "oldImport": {
@@ -2716,16 +2716,16 @@
}, },
"field": { "field": {
"pageTitle": { "pageTitle": {
"label": "" "label": "Naslov strani"
}, },
"metaTitle": { "metaTitle": {
"label": "" "label": "Meta naslov"
}, },
"logoImageUrl": { "logoImageUrl": {
"label": "" "label": "URL logotipa"
}, },
"faviconImageUrl": { "faviconImageUrl": {
"label": "" "label": "URL ikone"
}, },
"backgroundImageUrl": { "backgroundImageUrl": {
"label": "", "label": "",
@@ -2835,7 +2835,7 @@
"metaTitle": "" "metaTitle": ""
}, },
"setting": { "setting": {
"title": "", "title": "Nastavitve za {boardName} nadzorno ploščo",
"section": { "section": {
"general": { "general": {
"title": "Splošno", "title": "Splošno",
@@ -2844,9 +2844,9 @@
"layout": { "layout": {
"title": "Postavitev", "title": "Postavitev",
"responsive": { "responsive": {
"title": "", "title": "Predloga",
"action": { "action": {
"add": "" "add": "Dodaj predlogo"
} }
} }
}, },
@@ -2959,14 +2959,14 @@
"layout": { "layout": {
"field": { "field": {
"name": { "name": {
"label": "" "label": "Ime"
}, },
"columnCount": { "columnCount": {
"label": "" "label": "Število stolpcev"
}, },
"breakpoint": { "breakpoint": {
"label": "", "label": "Prekinitvene točke",
"description": "" "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": { "search": {
"placeholder": "", "placeholder": "Iskanje vsebine",
"nothingFound": "", "nothingFound": "",
"error": { "error": {
"fetch": "" "fetch": ""
+1 -1
View File
@@ -34,7 +34,7 @@
"@mantine/hooks": "^8.3.10", "@mantine/hooks": "^8.3.10",
"@tabler/icons-react": "^3.35.0", "@tabler/icons-react": "^3.35.0",
"mantine-react-table": "2.0.0-beta.9", "mantine-react-table": "2.0.0-beta.9",
"next": "16.1.0", "next": "16.1.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"svgson": "^5.3.1" "svgson": "^5.3.1"
+1 -1
View File
@@ -72,7 +72,7 @@
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"mantine-form-zod-resolver": "^1.3.0", "mantine-form-zod-resolver": "^1.3.0",
"mantine-react-table": "2.0.0-beta.9", "mantine-react-table": "2.0.0-beta.9",
"next": "16.1.0", "next": "16.1.1",
"react": "19.2.3", "react": "19.2.3",
"react-dom": "19.2.3", "react-dom": "19.2.3",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
@@ -47,7 +47,7 @@ export const SystemResourceMemoryChart = ({
return ( return (
<Paper px={3} py={2} withBorder shadow="md" radius="md"> <Paper px={3} py={2} withBorder shadow="md" radius="md">
<Text c="dimmed" size="xs"> <Text c="dimmed" size="xs">
{humanFileSize(value)} / {humanFileSize(totalCapacityInBytes)} ( {humanFileSize(Math.round(value))} / {humanFileSize(totalCapacityInBytes)} (
{Math.round((value / totalCapacityInBytes) * 100)}%) {Math.round((value / totalCapacityInBytes) * 100)}%)
</Text> </Text>
</Paper> </Paper>
@@ -22,6 +22,7 @@ export default function SystemResources({ integrationIds, options }: WidgetCompo
}); });
const memoryCapacityInBytes = const memoryCapacityInBytes =
(data[0]?.healthInfo.memAvailableInBytes ?? 0) + (data[0]?.healthInfo.memUsedInBytes ?? 0); (data[0]?.healthInfo.memAvailableInBytes ?? 0) + (data[0]?.healthInfo.memUsedInBytes ?? 0);
const [items, setItems] = useState<{ cpu: number; memory: number; network: { up: number; down: number } | null }[]>( const [items, setItems] = useState<{ cpu: number; memory: number; network: { up: number; down: number } | null }[]>(
data.map((item) => ({ data.map((item) => ({
cpu: item.healthInfo.cpuUtilization, cpu: item.healthInfo.cpuUtilization,
@@ -14,7 +14,7 @@ const labelDisplayModeOptions = {
export const { definition, componentLoader } = createWidgetDefinition("systemResources", { export const { definition, componentLoader } = createWidgetDefinition("systemResources", {
icon: IconGraphFilled, icon: IconGraphFilled,
supportedIntegrations: ["dashDot", "openmediavault", "truenas"], supportedIntegrations: ["dashDot", "openmediavault", "truenas", "unraid"],
createOptions() { createOptions() {
return optionsBuilder.from((factory) => ({ return optionsBuilder.from((factory) => ({
hasShadow: factory.switch({ defaultValue: true }), hasShadow: factory.switch({ defaultValue: true }),
+624 -361
View File
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -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
View File
@@ -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
+3 -3
View File
@@ -17,14 +17,14 @@
}, },
"prettier": "@homarr/prettier-config", "prettier": "@homarr/prettier-config",
"dependencies": { "dependencies": {
"@next/eslint-plugin-next": "16.1.0", "@next/eslint-plugin-next": "16.1.1",
"eslint-config-prettier": "^10.1.8", "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-import": "^2.32.0",
"eslint-plugin-jsx-a11y": "^6.10.2", "eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5", "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^6.1.1", "eslint-plugin-react-hooks": "^6.1.1",
"typescript-eslint": "^8.50.0" "typescript-eslint": "^8.50.1"
}, },
"devDependencies": { "devDependencies": {
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",