chore(release): automatic release v1.26.0

This commit is contained in:
homarr-releases[bot] authored and GitHub committed 2025-06-27 19:14:04 +00:00
commit 2c2e60aee6
84 files changed
+2570 -1573

No files matched your search

+1
View File
@@ -31,6 +31,7 @@ body:
label: Version label: Version
description: What version of Homarr are you running? description: What version of Homarr are you running?
options: options:
- 1.25.0
- 1.24.0 - 1.24.0
- 1.23.0 - 1.23.0
- 1.22.0 - 1.22.0
@@ -1,14 +0,0 @@
# https://github.com/webiny/action-conventional-commits?tab=readme-ov-file
name: "[Conventions] Semantic Commits"
on:
pull_request:
branches: [ dev ]
jobs:
build:
name: Conventional Commits
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: webiny/action-conventional-commits@v1.3.0
+1 -1
View File
@@ -1 +1 @@
22.16.0 22.17.0
+18 -18
View File
@@ -48,28 +48,28 @@
"@homarr/ui": "workspace:^0.1.0", "@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0", "@homarr/widgets": "workspace:^0.1.0",
"@mantine/colors-generator": "^8.1.1", "@mantine/colors-generator": "^8.1.2",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@mantine/dropzone": "^8.1.1", "@mantine/dropzone": "^8.1.2",
"@mantine/hooks": "^8.1.1", "@mantine/hooks": "^8.1.2",
"@mantine/modals": "^8.1.1", "@mantine/modals": "^8.1.2",
"@mantine/tiptap": "^8.1.1", "@mantine/tiptap": "^8.1.2",
"@million/lint": "1.0.14", "@million/lint": "1.0.14",
"@tabler/icons-react": "^3.34.0", "@tabler/icons-react": "^3.34.0",
"@tanstack/react-query": "^5.80.10", "@tanstack/react-query": "^5.81.4",
"@tanstack/react-query-devtools": "^5.80.10", "@tanstack/react-query-devtools": "^5.81.4",
"@tanstack/react-query-next-experimental": "^5.80.10", "@tanstack/react-query-next-experimental": "^5.81.4",
"@trpc/client": "^11.4.2", "@trpc/client": "^11.4.3",
"@trpc/next": "^11.4.2", "@trpc/next": "^11.4.3",
"@trpc/react-query": "^11.4.2", "@trpc/react-query": "^11.4.3",
"@trpc/server": "^11.4.2", "@trpc/server": "^11.4.3",
"@xterm/addon-canvas": "^0.7.0", "@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "0.10.0", "@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "^5.5.0", "@xterm/xterm": "^5.5.0",
"chroma-js": "^3.1.2", "chroma-js": "^3.1.2",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"dotenv": "^16.5.0", "dotenv": "^16.6.0",
"flag-icons": "^7.5.0", "flag-icons": "^7.5.0",
"glob": "^11.0.3", "glob": "^11.0.3",
"jotai": "^2.12.5", "jotai": "^2.12.5",
@@ -83,7 +83,7 @@
"react-simple-code-editor": "^0.14.1", "react-simple-code-editor": "^0.14.1",
"sass": "^1.89.2", "sass": "^1.89.2",
"superjson": "2.2.2", "superjson": "2.2.2",
"swagger-ui-react": "^5.25.2", "swagger-ui-react": "^5.25.3",
"use-deep-compare-effect": "^1.8.1", "use-deep-compare-effect": "^1.8.1",
"zod": "^3.25.67" "zod": "^3.25.67"
}, },
@@ -92,15 +92,15 @@
"@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/chroma-js": "3.1.1", "@types/chroma-js": "3.1.1",
"@types/node": "^22.15.32", "@types/node": "^22.15.33",
"@types/prismjs": "^1.26.5", "@types/prismjs": "^1.26.5",
"@types/react": "19.1.8", "@types/react": "19.1.8",
"@types/react-dom": "19.1.6", "@types/react-dom": "19.1.6",
"@types/swagger-ui-react": "^5.18.0", "@types/swagger-ui-react": "^5.18.0",
"concurrently": "^9.1.2", "concurrently": "^9.2.0",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"node-loader": "^2.1.0", "node-loader": "^2.1.0",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
} }
@@ -1,4 +1,4 @@
import { IconGrid3x3, IconKey, IconPassword, IconServer, IconUser } from "@tabler/icons-react"; import { IconGrid3x3, IconKey, IconMessage, IconPassword, IconServer, IconUser } from "@tabler/icons-react";
import type { IntegrationSecretKind } from "@homarr/definitions"; import type { IntegrationSecretKind } from "@homarr/definitions";
import type { TablerIcon } from "@homarr/ui"; import type { TablerIcon } from "@homarr/ui";
@@ -9,4 +9,5 @@ export const integrationSecretIcons = {
password: IconPassword, password: IconPassword,
realm: IconServer, realm: IconServer,
tokenId: IconGrid3x3, tokenId: IconGrid3x3,
topic: IconMessage,
} satisfies Record<IntegrationSecretKind, TablerIcon>; } satisfies Record<IntegrationSecretKind, TablerIcon>;
+4 -4
View File
@@ -36,19 +36,19 @@
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0", "@homarr/widgets": "workspace:^0.1.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"dotenv": "^16.5.0", "dotenv": "^16.6.0",
"superjson": "2.2.2", "superjson": "2.2.2",
"undici": "7.10.0" "undici": "7.11.0"
}, },
"devDependencies": { "devDependencies": {
"@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",
"@types/node": "^22.15.32", "@types/node": "^22.15.33",
"dotenv-cli": "^8.0.0", "dotenv-cli": "^8.0.0",
"esbuild": "^0.25.5", "esbuild": "^0.25.5",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"tsx": "4.20.3", "tsx": "4.20.3",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
+2 -2
View File
@@ -25,7 +25,7 @@
"@homarr/log": "workspace:^", "@homarr/log": "workspace:^",
"@homarr/redis": "workspace:^0.1.0", "@homarr/redis": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"dotenv": "^16.5.0", "dotenv": "^16.6.0",
"tsx": "4.20.3", "tsx": "4.20.3",
"ws": "^8.18.2" "ws": "^8.18.2"
}, },
@@ -36,7 +36,7 @@
"@types/ws": "^8.18.1", "@types/ws": "^8.18.1",
"esbuild": "^0.25.5", "esbuild": "^0.25.5",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
} }
+6 -6
View File
@@ -36,16 +36,16 @@
"@semantic-release/commit-analyzer": "^13.0.1", "@semantic-release/commit-analyzer": "^13.0.1",
"@semantic-release/git": "^10.0.1", "@semantic-release/git": "^10.0.1",
"@semantic-release/github": "^11.0.3", "@semantic-release/github": "^11.0.3",
"@semantic-release/npm": "^12.0.1", "@semantic-release/npm": "^12.0.2",
"@semantic-release/release-notes-generator": "^14.0.3", "@semantic-release/release-notes-generator": "^14.0.3",
"@turbo/gen": "^2.5.4", "@turbo/gen": "^2.5.4",
"@vitejs/plugin-react": "^4.5.2", "@vitejs/plugin-react": "^4.6.0",
"@vitest/coverage-v8": "^3.2.4", "@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4", "@vitest/ui": "^3.2.4",
"conventional-changelog-conventionalcommits": "^9.0.0", "conventional-changelog-conventionalcommits": "^9.0.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"jsdom": "^26.1.0", "jsdom": "^26.1.0",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"semantic-release": "^24.2.5", "semantic-release": "^24.2.5",
"testcontainers": "^11.0.3", "testcontainers": "^11.0.3",
"turbo": "^2.5.4", "turbo": "^2.5.4",
@@ -53,9 +53,9 @@
"vite-tsconfig-paths": "^5.1.4", "vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4" "vitest": "^3.2.4"
}, },
"packageManager": "pnpm@10.12.1", "packageManager": "pnpm@10.12.4",
"engines": { "engines": {
"node": ">=22.16.0" "node": ">=22.17.0"
}, },
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [
@@ -70,7 +70,7 @@
"tree-sitter-json" "tree-sitter-json"
], ],
"overrides": { "overrides": {
"proxmox-api>undici": "7.10.0" "proxmox-api>undici": "7.11.0"
}, },
"allowUnusedPatches": true, "allowUnusedPatches": true,
"ignoredBuiltDependencies": [ "ignoredBuiltDependencies": [
+6 -6
View File
@@ -41,11 +41,11 @@
"@homarr/server-settings": "workspace:^0.1.0", "@homarr/server-settings": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@kubernetes/client-node": "^1.3.0", "@kubernetes/client-node": "^1.3.0",
"@tanstack/react-query": "^5.80.10", "@tanstack/react-query": "^5.81.4",
"@trpc/client": "^11.4.2", "@trpc/client": "^11.4.3",
"@trpc/react-query": "^11.4.2", "@trpc/react-query": "^11.4.3",
"@trpc/server": "^11.4.2", "@trpc/server": "^11.4.3",
"@trpc/tanstack-react-query": "^11.4.2", "@trpc/tanstack-react-query": "^11.4.3",
"lodash.clonedeep": "^4.5.0", "lodash.clonedeep": "^4.5.0",
"next": "15.3.4", "next": "15.3.4",
"react": "19.1.0", "react": "19.1.0",
@@ -59,7 +59,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",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
} }
+2
View File
@@ -11,6 +11,7 @@ import { mediaTranscodingRouter } from "./media-transcoding";
import { minecraftRouter } from "./minecraft"; import { minecraftRouter } from "./minecraft";
import { networkControllerRouter } from "./network-controller"; import { networkControllerRouter } from "./network-controller";
import { notebookRouter } from "./notebook"; import { notebookRouter } from "./notebook";
import { notificationsRouter } from "./notifications";
import { optionsRouter } from "./options"; import { optionsRouter } from "./options";
import { releasesRouter } from "./releases"; import { releasesRouter } from "./releases";
import { rssFeedRouter } from "./rssFeed"; import { rssFeedRouter } from "./rssFeed";
@@ -37,4 +38,5 @@ export const widgetRouter = createTRPCRouter({
options: optionsRouter, options: optionsRouter,
releases: releasesRouter, releases: releasesRouter,
networkController: networkControllerRouter, networkController: networkControllerRouter,
notifications: notificationsRouter,
}); });
@@ -0,0 +1,64 @@
import { observable } from "@trpc/server/observable";
import type { Modify } from "@homarr/common/types";
import type { Integration } from "@homarr/db/schema";
import type { IntegrationKindByCategory } from "@homarr/definitions";
import { getIntegrationKindsByCategory } from "@homarr/definitions";
import type { Notification } from "@homarr/integrations";
import { notificationsRequestHandler } from "@homarr/request-handler/notifications";
import type { IntegrationAction } from "../../middlewares/integration";
import { createManyIntegrationMiddleware } from "../../middlewares/integration";
import { createTRPCRouter, publicProcedure } from "../../trpc";
const createNotificationsIntegrationMiddleware = (action: IntegrationAction) =>
createManyIntegrationMiddleware(action, ...getIntegrationKindsByCategory("notifications"));
export const notificationsRouter = createTRPCRouter({
getNotifications: publicProcedure
.unstable_concat(createNotificationsIntegrationMiddleware("query"))
.query(async ({ ctx }) => {
return await Promise.all(
ctx.integrations.map(async (integration) => {
const innerHandler = notificationsRequestHandler.handler(integration, {});
const { data, timestamp } = await innerHandler.getCachedOrUpdatedDataAsync({ forceUpdate: false });
return {
integration: {
id: integration.id,
name: integration.name,
kind: integration.kind,
updatedAt: timestamp,
},
data,
};
}),
);
}),
subscribeNotifications: publicProcedure
.unstable_concat(createNotificationsIntegrationMiddleware("query"))
.subscription(({ ctx }) => {
return observable<{
integration: Modify<Integration, { kind: IntegrationKindByCategory<"notifications"> }>;
data: Notification[];
}>((emit) => {
const unsubscribes: (() => void)[] = [];
for (const integrationWithSecrets of ctx.integrations) {
const { decryptedSecrets: _, ...integration } = integrationWithSecrets;
const innerHandler = notificationsRequestHandler.handler(integrationWithSecrets, {});
const unsubscribe = innerHandler.subscribe((data) => {
emit.next({
integration,
data,
});
});
unsubscribes.push(unsubscribe);
}
return () => {
unsubscribes.forEach((unsubscribe) => {
unsubscribe();
});
};
});
}),
});
+5 -5
View File
@@ -23,8 +23,8 @@
}, },
"prettier": "@homarr/prettier-config", "prettier": "@homarr/prettier-config",
"dependencies": { "dependencies": {
"@auth/core": "^0.39.1", "@auth/core": "^0.40.0",
"@auth/drizzle-adapter": "^1.9.1", "@auth/drizzle-adapter": "^1.10.0",
"@homarr/certificates": "workspace:^0.1.0", "@homarr/certificates": "workspace:^0.1.0",
"@homarr/common": "workspace:^0.1.0", "@homarr/common": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0", "@homarr/db": "workspace:^0.1.0",
@@ -34,9 +34,9 @@
"@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.1", "ldapts": "8.0.2",
"next": "15.3.4", "next": "15.3.4",
"next-auth": "5.0.0-beta.28", "next-auth": "5.0.0-beta.29",
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"zod": "^3.25.67" "zod": "^3.25.67"
@@ -48,7 +48,7 @@
"@types/bcrypt": "5.0.2", "@types/bcrypt": "5.0.2",
"@types/cookies": "0.9.1", "@types/cookies": "0.9.1",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
} }
+1 -1
View File
@@ -24,7 +24,7 @@
"dependencies": { "dependencies": {
"@homarr/common": "workspace:^0.1.0", "@homarr/common": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0", "@homarr/db": "workspace:^0.1.0",
"undici": "7.10.0" "undici": "7.11.0"
}, },
"devDependencies": { "devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
+1 -1
View File
@@ -28,7 +28,7 @@
"@homarr/common": "workspace:^0.1.0", "@homarr/common": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0", "@homarr/db": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"dotenv": "^16.5.0" "dotenv": "^16.6.0"
}, },
"devDependencies": { "devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0", "@homarr/eslint-config": "workspace:^0.2.0",
+1 -1
View File
@@ -33,7 +33,7 @@
"next": "15.3.4", "next": "15.3.4",
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"undici": "7.10.0", "undici": "7.11.0",
"zod": "^3.25.67", "zod": "^3.25.67",
"zod-validation-error": "^3.5.2" "zod-validation-error": "^3.5.2"
}, },
+2 -2
View File
@@ -10,11 +10,11 @@ const calculateTimeAgo = (timestamp: Date) => {
return dayjs().to(timestamp); return dayjs().to(timestamp);
}; };
export const useTimeAgo = (timestamp: Date) => { export const useTimeAgo = (timestamp: Date, updateFrequency = 1000) => {
const [timeAgo, setTimeAgo] = useState(calculateTimeAgo(timestamp)); const [timeAgo, setTimeAgo] = useState(calculateTimeAgo(timestamp));
useEffect(() => { useEffect(() => {
const intervalId = setInterval(() => setTimeAgo(calculateTimeAgo(timestamp)), 1000); // update every second const intervalId = setInterval(() => setTimeAgo(calculateTimeAgo(timestamp)), updateFrequency);
return () => clearInterval(intervalId); // clear interval on hook unmount return () => clearInterval(intervalId); // clear interval on hook unmount
}, [timestamp]); }, [timestamp]);
+1
View File
@@ -25,6 +25,7 @@ export const cronJobs = {
minecraftServerStatus: { preventManualExecution: false }, minecraftServerStatus: { preventManualExecution: false },
networkController: { preventManualExecution: false }, networkController: { preventManualExecution: false },
dockerContainers: { preventManualExecution: false }, dockerContainers: { preventManualExecution: false },
refreshNotifications: { preventManualExecution: false },
} satisfies Record<JobGroupKeys, { preventManualExecution?: boolean }>; } satisfies Record<JobGroupKeys, { preventManualExecution?: boolean }>;
/** /**
+2
View File
@@ -11,6 +11,7 @@ import { mediaRequestListJob, mediaRequestStatsJob } from "./jobs/integrations/m
import { mediaServerJob } from "./jobs/integrations/media-server"; import { mediaServerJob } from "./jobs/integrations/media-server";
import { mediaTranscodingJob } from "./jobs/integrations/media-transcoding"; import { mediaTranscodingJob } from "./jobs/integrations/media-transcoding";
import { networkControllerJob } from "./jobs/integrations/network-controller"; import { networkControllerJob } from "./jobs/integrations/network-controller";
import { refreshNotificationsJob } from "./jobs/integrations/notifications";
import { minecraftServerStatusJob } from "./jobs/minecraft-server-status"; import { minecraftServerStatusJob } from "./jobs/minecraft-server-status";
import { pingJob } from "./jobs/ping"; import { pingJob } from "./jobs/ping";
import { rssFeedsJob } from "./jobs/rss-feeds"; import { rssFeedsJob } from "./jobs/rss-feeds";
@@ -38,6 +39,7 @@ export const jobGroup = createCronJobGroup({
minecraftServerStatus: minecraftServerStatusJob, minecraftServerStatus: minecraftServerStatusJob,
dockerContainers: dockerContainersJob, dockerContainers: dockerContainersJob,
networkController: networkControllerJob, networkController: networkControllerJob,
refreshNotifications: refreshNotificationsJob,
}); });
export type JobGroupKeys = ReturnType<(typeof jobGroup)["getKeys"]>[number]; export type JobGroupKeys = ReturnType<(typeof jobGroup)["getKeys"]>[number];
@@ -0,0 +1,14 @@
import { EVERY_5_MINUTES } from "@homarr/cron-jobs-core/expressions";
import { createRequestIntegrationJobHandler } from "@homarr/request-handler/lib/cached-request-integration-job-handler";
import { notificationsRequestHandler } from "@homarr/request-handler/notifications";
import { createCronJob } from "../../lib";
export const refreshNotificationsJob = createCronJob("refreshNotifications", EVERY_5_MINUTES).withCallback(
createRequestIntegrationJobHandler(notificationsRequestHandler.handler, {
widgetKinds: ["notifications"],
getInput: {
notifications: (options) => options,
},
}),
);
+6 -6
View File
@@ -38,18 +38,18 @@
}, },
"prettier": "@homarr/prettier-config", "prettier": "@homarr/prettier-config",
"dependencies": { "dependencies": {
"@auth/core": "^0.39.1", "@auth/core": "^0.40.0",
"@homarr/common": "workspace:^0.1.0", "@homarr/common": "workspace:^0.1.0",
"@homarr/definitions": "workspace:^0.1.0", "@homarr/definitions": "workspace:^0.1.0",
"@homarr/env": "workspace:^0.1.0", "@homarr/env": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0", "@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0", "@homarr/server-settings": "workspace:^0.1.0",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@paralleldrive/cuid2": "^2.2.2", "@paralleldrive/cuid2": "^2.2.2",
"@testcontainers/mysql": "^11.0.3", "@testcontainers/mysql": "^11.0.3",
"better-sqlite3": "^11.10.0", "better-sqlite3": "^12.1.1",
"dotenv": "^16.5.0", "dotenv": "^16.6.0",
"drizzle-kit": "^0.31.1", "drizzle-kit": "^0.31.4",
"drizzle-orm": "^0.44.2", "drizzle-orm": "^0.44.2",
"drizzle-zod": "^0.7.1", "drizzle-zod": "^0.7.1",
"mysql2": "3.14.1" "mysql2": "3.14.1"
@@ -62,7 +62,7 @@
"dotenv-cli": "^8.0.0", "dotenv-cli": "^8.0.0",
"esbuild": "^0.25.5", "esbuild": "^0.25.5",
"eslint": "^9.29.0", "eslint": "^9.29.0",
"prettier": "^3.5.3", "prettier": "^3.6.2",
"tsx": "4.20.3", "tsx": "4.20.3",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
+9 -1
View File
@@ -7,6 +7,7 @@ export const integrationSecretKindObject = {
password: { isPublic: false }, password: { isPublic: false },
tokenId: { isPublic: true }, tokenId: { isPublic: true },
realm: { isPublic: true }, realm: { isPublic: true },
topic: { isPublic: true },
} satisfies Record<string, { isPublic: boolean }>; } satisfies Record<string, { isPublic: boolean }>;
export const integrationSecretKinds = objectKeys(integrationSecretKindObject); export const integrationSecretKinds = objectKeys(integrationSecretKindObject);
@@ -169,6 +170,12 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/unifi.png", iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/unifi.png",
category: ["networkController"], category: ["networkController"],
}, },
ntfy: {
name: "ntfy",
secretKinds: [["topic"], ["topic", "apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/ntfy.svg",
category: ["notifications"],
},
} as const satisfies Record<string, integrationDefinition>; } as const satisfies Record<string, integrationDefinition>;
export const integrationKinds = objectKeys(integrationDefs) as AtLeastOneOf<IntegrationKind>; export const integrationKinds = objectKeys(integrationDefs) as AtLeastOneOf<IntegrationKind>;
@@ -223,4 +230,5 @@ export type IntegrationCategory =
| "healthMonitoring" | "healthMonitoring"
| "search" | "search"
| "mediaTranscoding" | "mediaTranscoding"
| "networkController"; | "networkController"
| "notifications";
+1
View File
@@ -25,5 +25,6 @@ export const widgetKinds = [
"healthMonitoring", "healthMonitoring",
"releases", "releases",
"dockerContainers", "dockerContainers",
"notifications",
] as const; ] as const;
export type WidgetKind = (typeof widgetKinds)[number]; export type WidgetKind = (typeof widgetKinds)[number];
+1 -1
View File
@@ -26,7 +26,7 @@
"@homarr/common": "workspace:^0.1.0", "@homarr/common": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@mantine/form": "^8.1.1", "@mantine/form": "^8.1.2",
"zod": "^3.25.67" "zod": "^3.25.67"
}, },
"devDependencies": { "devDependencies": {
+1 -1
View File
@@ -29,7 +29,7 @@
"@homarr/notifications": "workspace:^0.1.0", "@homarr/notifications": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"react": "19.1.0", "react": "19.1.0",
"zod": "^3.25.67" "zod": "^3.25.67"
}, },
+2 -2
View File
@@ -38,11 +38,11 @@
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@jellyfin/sdk": "^0.11.0", "@jellyfin/sdk": "^0.11.0",
"maria2": "^0.4.0", "maria2": "^0.4.1",
"node-ical": "^0.20.1", "node-ical": "^0.20.1",
"proxmox-api": "1.1.1", "proxmox-api": "1.1.1",
"tsdav": "^2.1.5", "tsdav": "^2.1.5",
"undici": "7.10.0", "undici": "7.11.0",
"xml2js": "^0.6.2", "xml2js": "^0.6.2",
"zod": "^3.25.67" "zod": "^3.25.67"
}, },
@@ -21,6 +21,7 @@ import { ReadarrIntegration } from "../media-organizer/readarr/readarr-integrati
import { SonarrIntegration } from "../media-organizer/sonarr/sonarr-integration"; import { SonarrIntegration } from "../media-organizer/sonarr/sonarr-integration";
import { TdarrIntegration } from "../media-transcoding/tdarr-integration"; import { TdarrIntegration } from "../media-transcoding/tdarr-integration";
import { NextcloudIntegration } from "../nextcloud/nextcloud.integration"; import { NextcloudIntegration } from "../nextcloud/nextcloud.integration";
import { NTFYIntegration } from "../ntfy/ntfy-integration";
import { OpenMediaVaultIntegration } from "../openmediavault/openmediavault-integration"; import { OpenMediaVaultIntegration } from "../openmediavault/openmediavault-integration";
import { OverseerrIntegration } from "../overseerr/overseerr-integration"; import { OverseerrIntegration } from "../overseerr/overseerr-integration";
import { createPiHoleIntegrationAsync } from "../pi-hole/pi-hole-integration-factory"; import { createPiHoleIntegrationAsync } from "../pi-hole/pi-hole-integration-factory";
@@ -92,6 +93,7 @@ export const integrationCreators = {
emby: EmbyIntegration, emby: EmbyIntegration,
nextcloud: NextcloudIntegration, nextcloud: NextcloudIntegration,
unifiController: UnifiControllerIntegration, unifiController: UnifiControllerIntegration,
ntfy: NTFYIntegration,
} 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> = {
+6 -4
View File
@@ -1,26 +1,27 @@
// General integrations // General integrations
export { AdGuardHomeIntegration } from "./adguard-home/adguard-home-integration"; export { AdGuardHomeIntegration } from "./adguard-home/adguard-home-integration";
export { Aria2Integration } from "./download-client/aria2/aria2-integration";
export { DelugeIntegration } from "./download-client/deluge/deluge-integration"; export { DelugeIntegration } from "./download-client/deluge/deluge-integration";
export { NzbGetIntegration } from "./download-client/nzbget/nzbget-integration"; export { NzbGetIntegration } from "./download-client/nzbget/nzbget-integration";
export { QBitTorrentIntegration } from "./download-client/qbittorrent/qbittorrent-integration"; export { QBitTorrentIntegration } from "./download-client/qbittorrent/qbittorrent-integration";
export { SabnzbdIntegration } from "./download-client/sabnzbd/sabnzbd-integration"; export { SabnzbdIntegration } from "./download-client/sabnzbd/sabnzbd-integration";
export { TransmissionIntegration } from "./download-client/transmission/transmission-integration"; export { TransmissionIntegration } from "./download-client/transmission/transmission-integration";
export { Aria2Integration } from "./download-client/aria2/aria2-integration";
export { HomeAssistantIntegration } from "./homeassistant/homeassistant-integration"; export { HomeAssistantIntegration } from "./homeassistant/homeassistant-integration";
export { DownloadClientIntegration } from "./interfaces/downloads/download-client-integration"; export { DownloadClientIntegration } from "./interfaces/downloads/download-client-integration";
export { JellyfinIntegration } from "./jellyfin/jellyfin-integration"; export { JellyfinIntegration } from "./jellyfin/jellyfin-integration";
export { JellyseerrIntegration } from "./jellyseerr/jellyseerr-integration"; export { JellyseerrIntegration } from "./jellyseerr/jellyseerr-integration";
export { LidarrIntegration } from "./media-organizer/lidarr/lidarr-integration";
export { RadarrIntegration } from "./media-organizer/radarr/radarr-integration"; export { RadarrIntegration } from "./media-organizer/radarr/radarr-integration";
export { ReadarrIntegration } from "./media-organizer/readarr/readarr-integration";
export { SonarrIntegration } from "./media-organizer/sonarr/sonarr-integration"; export { SonarrIntegration } from "./media-organizer/sonarr/sonarr-integration";
export { NextcloudIntegration } from "./nextcloud/nextcloud.integration";
export { NTFYIntegration } from "./ntfy/ntfy-integration";
export { OpenMediaVaultIntegration } from "./openmediavault/openmediavault-integration"; export { OpenMediaVaultIntegration } from "./openmediavault/openmediavault-integration";
export { OverseerrIntegration } from "./overseerr/overseerr-integration"; export { OverseerrIntegration } from "./overseerr/overseerr-integration";
export { PiHoleIntegrationV5 } from "./pi-hole/v5/pi-hole-integration-v5"; export { PiHoleIntegrationV5 } from "./pi-hole/v5/pi-hole-integration-v5";
export { PiHoleIntegrationV6 } from "./pi-hole/v6/pi-hole-integration-v6"; 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 { LidarrIntegration } from "./media-organizer/lidarr/lidarr-integration";
export { ReadarrIntegration } from "./media-organizer/readarr/readarr-integration";
export { NextcloudIntegration } from "./nextcloud/nextcloud.integration";
// Types // Types
export type { IntegrationInput } from "./base/integration"; export type { IntegrationInput } from "./base/integration";
@@ -34,6 +35,7 @@ export type { StreamSession } from "./interfaces/media-server/session";
export type { TdarrQueue } from "./interfaces/media-transcoding/queue"; export type { TdarrQueue } from "./interfaces/media-transcoding/queue";
export type { TdarrPieSegment, TdarrStatistics } from "./interfaces/media-transcoding/statistics"; export type { TdarrPieSegment, TdarrStatistics } from "./interfaces/media-transcoding/statistics";
export type { TdarrWorker } from "./interfaces/media-transcoding/workers"; export type { TdarrWorker } from "./interfaces/media-transcoding/workers";
export type { Notification } from "./interfaces/notifications/notification";
// Schemas // Schemas
export { downloadClientItemSchema } from "./interfaces/downloads/download-client-items"; export { downloadClientItemSchema } from "./interfaces/downloads/download-client-items";
@@ -43,6 +43,7 @@ export interface MediaRequestStats {
users: RequestUser[]; users: RequestUser[];
} }
// https://github.com/fallenbagel/jellyseerr/blob/0fd03f38480f853e7015ad9229ed98160e37602e/server/constants/media.ts#L1
export enum MediaRequestStatus { export enum MediaRequestStatus {
PendingApproval = 1, PendingApproval = 1,
Approved = 2, Approved = 2,
@@ -51,6 +52,7 @@ export enum MediaRequestStatus {
Completed = 5, Completed = 5,
} }
// https://github.com/fallenbagel/jellyseerr/blob/0fd03f38480f853e7015ad9229ed98160e37602e/server/constants/media.ts#L14
export enum MediaAvailability { export enum MediaAvailability {
Unknown = 1, Unknown = 1,
Pending = 2, Pending = 2,
@@ -58,4 +60,5 @@ export enum MediaAvailability {
PartiallyAvailable = 4, PartiallyAvailable = 4,
Available = 5, Available = 5,
Blacklisted = 6, Blacklisted = 6,
Deleted = 7,
} }
@@ -0,0 +1,6 @@
export interface Notification {
id: string;
time: Date;
title: string;
body: string;
}
@@ -0,0 +1,6 @@
import { Integration } from "../../base/integration";
import type { Notification } from "./notification";
export abstract class NotificationsIntegration extends Integration {
public abstract getNotificationsAsync(): Promise<Notification[]>;
}
@@ -0,0 +1,65 @@
import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
import { ResponseError } from "@homarr/common/server";
import type { IntegrationTestingInput } from "../base/integration";
import type { TestingResult } from "../base/test-connection/test-connection-service";
import type { Notification } from "../interfaces/notifications/notification";
import { NotificationsIntegration } from "../interfaces/notifications/notifications-integration";
import { ntfyNotificationSchema } from "./ntfy-schema";
export class NTFYIntegration extends NotificationsIntegration {
public async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
await input.fetchAsync(this.url("/v1/account"), { headers: this.getHeaders() });
return { success: true };
}
private getTopicURL() {
return this.url(`/${encodeURIComponent(super.getSecretValue("topic"))}/json`, { poll: 1 });
}
private getHeaders() {
return this.hasSecretValue("apiKey") ? { Authorization: `Bearer ${super.getSecretValue("apiKey")}` } : {};
}
public async getNotificationsAsync() {
const url = this.getTopicURL();
const notifications = await Promise.all(
(
await fetchWithTrustedCertificatesAsync(url, { headers: this.getHeaders() })
.then((response) => {
if (!response.ok) throw new ResponseError(response);
return response.text();
})
.catch((error) => {
if (error instanceof Error) throw error;
else {
throw new Error("Error communicating with ntfy");
}
})
)
// response is provided as individual lines of JSON
.split("\n")
.map(async (line) => {
// ignore empty lines
if (line.length === 0) return null;
const json = JSON.parse(line) as unknown;
const parsed = await ntfyNotificationSchema.parseAsync(json);
if (parsed.event === "message") return parsed;
// ignore non-event messages
else return null;
}),
);
return notifications
.filter((notification) => notification !== null)
.map((notification): Notification => {
const topicURL = this.url(`/${notification.topic}`);
return {
id: notification.id,
time: new Date(notification.time * 1000),
title: notification.title ?? topicURL.hostname + topicURL.pathname,
body: notification.message,
};
});
}
}
@@ -0,0 +1,12 @@
import { z } from "zod";
// There are more properties, see: https://docs.ntfy.sh/subscribe/api/#json-message-format
// Not all properties are required for this use case.
export const ntfyNotificationSchema = z.object({
id: z.string(),
time: z.number(),
event: z.string(), // we only care about "message"
topic: z.string(),
title: z.optional(z.string()),
message: z.string(),
});
+1 -1
View File
@@ -33,7 +33,7 @@
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0", "@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@tabler/icons-react": "^3.34.0", "@tabler/icons-react": "^3.34.0",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"next": "15.3.4", "next": "15.3.4",
+2 -2
View File
@@ -24,8 +24,8 @@
"dependencies": { "dependencies": {
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0", "@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@mantine/hooks": "^8.1.1", "@mantine/hooks": "^8.1.2",
"react": "19.1.0" "react": "19.1.0"
}, },
"devDependencies": { "devDependencies": {
+1 -1
View File
@@ -24,7 +24,7 @@
"prettier": "@homarr/prettier-config", "prettier": "@homarr/prettier-config",
"dependencies": { "dependencies": {
"@homarr/ui": "workspace:^0.1.0", "@homarr/ui": "workspace:^0.1.0",
"@mantine/notifications": "^8.1.1", "@mantine/notifications": "^8.1.2",
"@tabler/icons-react": "^3.34.0" "@tabler/icons-react": "^3.34.0"
}, },
"devDependencies": { "devDependencies": {
+2 -2
View File
@@ -37,8 +37,8 @@
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0", "@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@mantine/hooks": "^8.1.1", "@mantine/hooks": "^8.1.2",
"adm-zip": "0.5.16", "adm-zip": "0.5.16",
"next": "15.3.4", "next": "15.3.4",
"react": "19.1.0", "react": "19.1.0",
@@ -0,0 +1,20 @@
import dayjs from "dayjs";
import type { IntegrationKindByCategory } from "@homarr/definitions";
import type { Notification } from "@homarr/integrations";
import { createIntegrationAsync } from "@homarr/integrations";
import { createCachedIntegrationRequestHandler } from "./lib/cached-integration-request-handler";
export const notificationsRequestHandler = createCachedIntegrationRequestHandler<
Notification[],
IntegrationKindByCategory<"notifications">,
Record<string, never>
>({
async requestAsync(integration) {
const integrationInstance = await createIntegrationAsync(integration);
return await integrationInstance.getNotificationsAsync();
},
cacheDuration: dayjs.duration(5, "minutes"),
queryKey: "notificationsJobStatus",
});
+1 -1
View File
@@ -26,7 +26,7 @@
"@homarr/api": "workspace:^0.1.0", "@homarr/api": "workspace:^0.1.0",
"@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.1.1", "@mantine/dates": "^8.1.2",
"next": "15.3.4", "next": "15.3.4",
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0" "react-dom": "19.1.0"
+3 -3
View File
@@ -33,9 +33,9 @@
"@homarr/settings": "workspace:^0.1.0", "@homarr/settings": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0", "@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@mantine/hooks": "^8.1.1", "@mantine/hooks": "^8.1.2",
"@mantine/spotlight": "^8.1.1", "@mantine/spotlight": "^8.1.2",
"@tabler/icons-react": "^3.34.0", "@tabler/icons-react": "^3.34.0",
"jotai": "^2.12.5", "jotai": "^2.12.5",
"next": "15.3.4", "next": "15.3.4",
+1 -1
View File
@@ -33,7 +33,7 @@
"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": "15.3.4", "next": "15.3.4",
"next-intl": "4.1.0", "next-intl": "4.3.1",
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0" "react-dom": "19.1.0"
}, },
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "", "partiallyAvailable": "",
"available": "" "available": "",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "领域", "label": "领域",
"newLabel": "新领域" "newLabel": "新领域"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "等待处理", "pending": "等待处理",
"processing": "处理中", "processing": "处理中",
"partiallyAvailable": "部分", "partiallyAvailable": "部分",
"available": "可用" "available": "可用",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "待处理", "pending": "待处理",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "获取网络控制器概述失败" "internalServerError": "获取网络控制器概述失败"
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "网络控制器" "label": "网络控制器"
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "Docker 容器" "label": "Docker 容器"
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Částečně dostupné", "partiallyAvailable": "Částečně dostupné",
"available": "K dispozici" "available": "K dispozici",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Realm", "label": "Realm",
"newLabel": "Nyt realm" "newLabel": "Nyt realm"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "Afventende", "pending": "Afventende",
"processing": "Behandler", "processing": "Behandler",
"partiallyAvailable": "Delvis", "partiallyAvailable": "Delvis",
"available": "Tilgængelig" "available": "Tilgængelig",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "Afventende", "pending": "Afventende",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "Kunne ikke hente Netværkskontroloversigt" "internalServerError": "Kunne ikke hente Netværkskontroloversigt"
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "Netværkskontroller" "label": "Netværkskontroller"
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "Docker containers" "label": "Docker containers"
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Bereich", "label": "Bereich",
"newLabel": "Neuer Bereich" "newLabel": "Neuer Bereich"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "Ausstehend", "pending": "Ausstehend",
"processing": "In Bearbeitung", "processing": "In Bearbeitung",
"partiallyAvailable": "Teilweise", "partiallyAvailable": "Teilweise",
"available": "Verfügbar" "available": "Verfügbar",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "Ausstehend", "pending": "Ausstehend",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+36 -21
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Bereich", "label": "Bereich",
"newLabel": "Neuer Bereich" "newLabel": "Neuer Bereich"
},
"topic": {
"label": "Thema",
"newLabel": "Neues Thema erstellen"
} }
} }
}, },
@@ -1758,7 +1762,7 @@
"label": "Speicher-Info anzeigen" "label": "Speicher-Info anzeigen"
}, },
"showUptime": { "showUptime": {
"label": "" "label": "Laufzeit anzeigen"
}, },
"fileSystem": { "fileSystem": {
"label": "Dateisystem Info anzeigen" "label": "Dateisystem Info anzeigen"
@@ -1767,7 +1771,7 @@
"label": "Standard Tab" "label": "Standard Tab"
}, },
"visibleClusterSections": { "visibleClusterSections": {
"label": "" "label": "Sichtbare Cluster-Abschnitte"
}, },
"sectionIndicatorRequirement": { "sectionIndicatorRequirement": {
"label": "Anforderung der Sektionsindikatoren" "label": "Anforderung der Sektionsindikatoren"
@@ -1839,11 +1843,11 @@
} }
}, },
"dockerContainers": { "dockerContainers": {
"name": "", "name": "Docker Statistiken",
"description": "", "description": "Statistiken Ihrer Container (Dieses Widget kann nur mit Administratorrechten hinzugefügt werden)",
"option": {}, "option": {},
"error": { "error": {
"internalServerError": "" "internalServerError": "Fehler beim Abrufen der Container Statistiken"
} }
}, },
"common": { "common": {
@@ -1961,8 +1965,8 @@
"label": "Filter zur Berechnung des Verhältnisses verwenden" "label": "Filter zur Berechnung des Verhältnisses verwenden"
}, },
"limitPerIntegration": { "limitPerIntegration": {
"label": "", "label": "Elemente pro Integration begrenzen",
"description": "" "description": "Dies begrenzt die Anzahl der Elemente pro Integration, jedoch nicht global"
} }
}, },
"errors": { "errors": {
@@ -2088,7 +2092,9 @@
"pending": "Ausstehend", "pending": "Ausstehend",
"processing": "In Bearbeitung", "processing": "In Bearbeitung",
"partiallyAvailable": "Teilweise", "partiallyAvailable": "Teilweise",
"available": "Verfügbar" "available": "Verfügbar",
"blacklisted": "Gesperrt",
"deleted": "Gelöscht"
}, },
"status": { "status": {
"pending": "Ausstehend", "pending": "Ausstehend",
@@ -2227,13 +2233,13 @@
"label": "Repository hinzufügen" "label": "Repository hinzufügen"
}, },
"importRepositories": { "importRepositories": {
"label": "", "label": "Von Docker importieren",
"loading": "", "loading": "Lade Docker Images",
"noImagesFound": "", "noImagesFound": "Keine Docker Images gefunden",
"listFoundImages": "", "listFoundImages": "Liste der gefundenen Images",
"listAlreadyImportedImages": "", "listAlreadyImportedImages": "Liste der bereits importierten Images",
"allImagesAlreadyImported": "", "allImagesAlreadyImported": "Alle Images wurden bereits importiert",
"onlyAdminCanImport": "" "onlyAdminCanImport": "Nur Administratoren können vom Docker importieren"
}, },
"provider": { "provider": {
"label": "Anbieter" "label": "Anbieter"
@@ -2276,7 +2282,7 @@
} }
}, },
"importForm": { "importForm": {
"title": "" "title": "Von Docker importieren"
}, },
"example": { "example": {
"label": "Beispiel" "label": "Beispiel"
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "Fehler beim Abrufen der Netzwerk Controller Zusammenfassung" "internalServerError": "Fehler beim Abrufen der Netzwerk Controller Zusammenfassung"
} }
},
"notifications": {
"name": "Benachrichtigungen",
"description": "Benachrichtigungshistorie von einer Integration anzeigen",
"noItems": "Keine Benachrichtigungen zum Anzeigen.",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,8 +3134,11 @@
"networkController": { "networkController": {
"label": "Netzwerk Controller" "label": "Netzwerk Controller"
}, },
"refreshNotifications": {
"label": "Benachrichtigungs Updater"
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": "Docker Container"
} }
} }
}, },
@@ -3189,7 +3204,7 @@
"updated": "Aktualisiert {when}", "updated": "Aktualisiert {when}",
"search": "{count} Container durchsuchen", "search": "{count} Container durchsuchen",
"selected": "{selectCount} von {totalCount} ausgewählten Containern", "selected": "{selectCount} von {totalCount} ausgewählten Containern",
"footer": "" "footer": "Insgesamt {count} Container"
}, },
"field": { "field": {
"name": { "name": {
@@ -3209,10 +3224,10 @@
}, },
"stats": { "stats": {
"cpu": { "cpu": {
"label": "" "label": "CPU"
}, },
"memory": { "memory": {
"label": "" "label": "Speicher"
} }
}, },
"containerImage": { "containerImage": {
@@ -3223,7 +3238,7 @@
} }
}, },
"action": { "action": {
"title": "", "title": "Aktionen",
"start": { "start": {
"label": "Starten", "label": "Starten",
"notification": { "notification": {
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Μερικώς", "partiallyAvailable": "Μερικώς",
"available": "Διαθέσιμο" "available": "Διαθέσιμο",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Realm", "label": "Realm",
"newLabel": "New realm" "newLabel": "New realm"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "", "partiallyAvailable": "",
"available": "" "available": "",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Realm", "label": "Realm",
"newLabel": "New realm" "newLabel": "New realm"
},
"topic": {
"label": "Topic",
"newLabel": "New topic"
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "Pending", "pending": "Pending",
"processing": "Processing", "processing": "Processing",
"partiallyAvailable": "Partial", "partiallyAvailable": "Partial",
"available": "Available" "available": "Available",
"blacklisted": "Blacklisted",
"deleted": "Deleted"
}, },
"status": { "status": {
"pending": "Pending", "pending": "Pending",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "Failed to fetch Network Controller Summary" "internalServerError": "Failed to fetch Network Controller Summary"
} }
},
"notifications": {
"name": "Notifications",
"description": "Display notification history from an integration",
"noItems": "No notifications to display.",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "Network Controller" "label": "Network Controller"
}, },
"refreshNotifications": {
"label": "Notification Updater"
},
"dockerContainers": { "dockerContainers": {
"label": "Docker containers" "label": "Docker containers"
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Parcial", "partiallyAvailable": "Parcial",
"available": "Disponible" "available": "Disponible",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "", "partiallyAvailable": "",
"available": "" "available": "",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Domaine", "label": "Domaine",
"newLabel": "Nouveau domaine" "newLabel": "Nouveau domaine"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "En attente", "pending": "En attente",
"processing": "Traitement en cours", "processing": "Traitement en cours",
"partiallyAvailable": "Partiel", "partiallyAvailable": "Partiel",
"available": "Disponible" "available": "Disponible",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "En attente", "pending": "En attente",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+24 -9
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "תחום", "label": "תחום",
"newLabel": "תחום חדש" "newLabel": "תחום חדש"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "בהמתנה", "pending": "בהמתנה",
"processing": "מעבד", "processing": "מעבד",
"partiallyAvailable": "חלקי", "partiallyAvailable": "חלקי",
"available": "זמין" "available": "זמין",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "ממתין", "pending": "ממתין",
@@ -2227,13 +2233,13 @@
"label": "הוסף מאגר" "label": "הוסף מאגר"
}, },
"importRepositories": { "importRepositories": {
"label": "", "label": "ייבוא מדוקר",
"loading": "", "loading": "טוען תמונות דוקר",
"noImagesFound": "", "noImagesFound": "לא נמצאו תמונות דוקר",
"listFoundImages": "", "listFoundImages": "רשימת התמונות שנמצאו",
"listAlreadyImportedImages": "", "listAlreadyImportedImages": "רשימת התמונות שכבר יובאו",
"allImagesAlreadyImported": "", "allImagesAlreadyImported": "כל התמונות כבר יובאו",
"onlyAdminCanImport": "" "onlyAdminCanImport": "רק מנהלים יכולים לייבא מדוקר"
}, },
"provider": { "provider": {
"label": "ספק" "label": "ספק"
@@ -2276,7 +2282,7 @@
} }
}, },
"importForm": { "importForm": {
"title": "" "title": "ייבוא מדוקר"
}, },
"example": { "example": {
"label": "דוגמא" "label": "דוגמא"
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "אחזור תקציר בקר הרשת נכשל" "internalServerError": "אחזור תקציר בקר הרשת נכשל"
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "בקר רשת" "label": "בקר רשת"
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "מכולות דוקר" "label": "מכולות דוקר"
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "", "partiallyAvailable": "",
"available": "" "available": "",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "Feldolgozás", "processing": "Feldolgozás",
"partiallyAvailable": "Részleges", "partiallyAvailable": "Részleges",
"available": "Elérhető" "available": "Elérhető",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Parziale", "partiallyAvailable": "Parziale",
"available": "Disponibile" "available": "Disponibile",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
File diff suppressed because it is too large. Load diff
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "", "partiallyAvailable": "",
"available": "" "available": "",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Dalis", "partiallyAvailable": "Dalis",
"available": "Galima" "available": "Galima",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Daļējs", "partiallyAvailable": "Daļējs",
"available": "Pieejams" "available": "Pieejams",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Realm", "label": "Realm",
"newLabel": "Nieuwe Realm" "newLabel": "Nieuwe Realm"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "In afwachting", "pending": "In afwachting",
"processing": "Verwerken", "processing": "Verwerken",
"partiallyAvailable": "Gedeeltelijk", "partiallyAvailable": "Gedeeltelijk",
"available": "Beschikbaar" "available": "Beschikbaar",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "In afwachting", "pending": "In afwachting",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "Netwerkcontroller samenvatting ophalen mislukt" "internalServerError": "Netwerkcontroller samenvatting ophalen mislukt"
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "Netwerkcontroller" "label": "Netwerkcontroller"
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Område", "label": "Område",
"newLabel": "Nytt område" "newLabel": "Nytt område"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "Pågår", "pending": "Pågår",
"processing": "Prosesserer", "processing": "Prosesserer",
"partiallyAvailable": "Delvis", "partiallyAvailable": "Delvis",
"available": "Tilgjengelig" "available": "Tilgjengelig",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "Venter", "pending": "Venter",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "Oczekujący", "pending": "Oczekujący",
"processing": "Przetwarzanie", "processing": "Przetwarzanie",
"partiallyAvailable": "", "partiallyAvailable": "",
"available": "Dostępne" "available": "Dostępne",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Parcial", "partiallyAvailable": "Parcial",
"available": "Disponível" "available": "Disponível",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Parțial", "partiallyAvailable": "Parțial",
"available": "Disponibil" "available": "Disponibil",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Область", "label": "Область",
"newLabel": "Новая область" "newLabel": "Новая область"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "В ожидании", "pending": "В ожидании",
"processing": "Обработка", "processing": "Обработка",
"partiallyAvailable": "Частично доступно", "partiallyAvailable": "Частично доступно",
"available": "Доступно" "available": "Доступно",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "В ожидании", "pending": "В ожидании",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Ríša", "label": "Ríša",
"newLabel": "Nová ríša" "newLabel": "Nová ríša"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "Čakajúce", "pending": "Čakajúce",
"processing": "Spracovanie", "processing": "Spracovanie",
"partiallyAvailable": "Čiastočný", "partiallyAvailable": "Čiastočný",
"available": "K dispozícii" "available": "K dispozícii",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "Čakajúce", "pending": "Čakajúce",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "Nepodarilo sa načítať súhrn sieťového ovládača" "internalServerError": "Nepodarilo sa načítať súhrn sieťového ovládača"
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "Sieťový ovládač" "label": "Sieťový ovládač"
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "Docker kontajnery" "label": "Docker kontajnery"
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "", "partiallyAvailable": "",
"available": "" "available": "",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Delmängd", "partiallyAvailable": "Delmängd",
"available": "Tillgänglig" "available": "Tillgänglig",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "Erişim Alanı", "label": "Erişim Alanı",
"newLabel": "Yeni erişim alanı" "newLabel": "Yeni erişim alanı"
},
"topic": {
"label": "Konu",
"newLabel": "Yeni konu"
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "Bekleyen", "pending": "Bekleyen",
"processing": "İşlemde", "processing": "İşlemde",
"partiallyAvailable": "Kısmi", "partiallyAvailable": "Kısmi",
"available": "Mevcut" "available": "Mevcut",
"blacklisted": "Engellenenler",
"deleted": "Silinen"
}, },
"status": { "status": {
"pending": "Bekleyen", "pending": "Bekleyen",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "Ağ Denetleyicisi Özeti alınamadı" "internalServerError": "Ağ Denetleyicisi Özeti alınamadı"
} }
},
"notifications": {
"name": "Bildirimler",
"description": "Entegrasyonların bildirim geçmişini görüntüle",
"noItems": "Görüntülenecek bildirim yok.",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "Ağ Denetleyicisi" "label": "Ağ Denetleyicisi"
}, },
"refreshNotifications": {
"label": "Bildirim Güncelleyici"
},
"dockerContainers": { "dockerContainers": {
"label": "Docker konteynerleri" "label": "Docker konteynerleri"
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "В очікуванні", "pending": "В очікуванні",
"processing": "В обробці", "processing": "В обробці",
"partiallyAvailable": "Частково доступно", "partiallyAvailable": "Частково доступно",
"available": "Доступно" "available": "Доступно",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "", "label": "",
"newLabel": "" "newLabel": ""
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "", "pending": "",
"processing": "", "processing": "",
"partiallyAvailable": "Một phần", "partiallyAvailable": "Một phần",
"available": "Khả dụng" "available": "Khả dụng",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "", "pending": "",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "" "internalServerError": ""
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "" "label": ""
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+16 -1
View File
@@ -936,6 +936,10 @@
"realm": { "realm": {
"label": "領域", "label": "領域",
"newLabel": "新領域" "newLabel": "新領域"
},
"topic": {
"label": "",
"newLabel": ""
} }
} }
}, },
@@ -2088,7 +2092,9 @@
"pending": "等待處理中", "pending": "等待處理中",
"processing": "處理中", "processing": "處理中",
"partiallyAvailable": "部分", "partiallyAvailable": "部分",
"available": "待定" "available": "待定",
"blacklisted": "",
"deleted": ""
}, },
"status": { "status": {
"pending": "待處理", "pending": "待處理",
@@ -2357,6 +2363,12 @@
"error": { "error": {
"internalServerError": "無法獲取網路控制總覽" "internalServerError": "無法獲取網路控制總覽"
} }
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
} }
}, },
"widgetPreview": { "widgetPreview": {
@@ -3122,6 +3134,9 @@
"networkController": { "networkController": {
"label": "網路控制" "label": "網路控制"
}, },
"refreshNotifications": {
"label": ""
},
"dockerContainers": { "dockerContainers": {
"label": "" "label": ""
} }
+3 -3
View File
@@ -29,9 +29,9 @@
"@homarr/log": "workspace:^0.1.0", "@homarr/log": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@mantine/dates": "^8.1.1", "@mantine/dates": "^8.1.2",
"@mantine/hooks": "^8.1.1", "@mantine/hooks": "^8.1.2",
"@tabler/icons-react": "^3.34.0", "@tabler/icons-react": "^3.34.0",
"mantine-react-table": "2.0.0-beta.9", "mantine-react-table": "2.0.0-beta.9",
"next": "15.3.4", "next": "15.3.4",
+19 -19
View File
@@ -48,25 +48,25 @@
"@homarr/translation": "workspace:^0.1.0", "@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0", "@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0", "@homarr/validation": "workspace:^0.1.0",
"@mantine/charts": "^8.1.1", "@mantine/charts": "^8.1.2",
"@mantine/core": "^8.1.1", "@mantine/core": "^8.1.2",
"@mantine/hooks": "^8.1.1", "@mantine/hooks": "^8.1.2",
"@tabler/icons-react": "^3.34.0", "@tabler/icons-react": "^3.34.0",
"@tiptap/extension-color": "2.22.0", "@tiptap/extension-color": "2.23.0",
"@tiptap/extension-highlight": "2.22.0", "@tiptap/extension-highlight": "2.23.0",
"@tiptap/extension-image": "2.22.0", "@tiptap/extension-image": "2.23.0",
"@tiptap/extension-link": "^2.22.0", "@tiptap/extension-link": "^2.23.0",
"@tiptap/extension-table": "2.22.0", "@tiptap/extension-table": "2.23.0",
"@tiptap/extension-table-cell": "2.22.0", "@tiptap/extension-table-cell": "2.23.0",
"@tiptap/extension-table-header": "2.22.0", "@tiptap/extension-table-header": "2.23.0",
"@tiptap/extension-table-row": "2.22.0", "@tiptap/extension-table-row": "2.23.0",
"@tiptap/extension-task-item": "2.22.0", "@tiptap/extension-task-item": "2.23.0",
"@tiptap/extension-task-list": "2.22.0", "@tiptap/extension-task-list": "2.23.0",
"@tiptap/extension-text-align": "2.22.0", "@tiptap/extension-text-align": "2.23.0",
"@tiptap/extension-text-style": "2.22.0", "@tiptap/extension-text-style": "2.23.0",
"@tiptap/extension-underline": "2.22.0", "@tiptap/extension-underline": "2.23.0",
"@tiptap/react": "^2.22.0", "@tiptap/react": "^2.23.0",
"@tiptap/starter-kit": "^2.22.0", "@tiptap/starter-kit": "^2.23.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",
"mantine-react-table": "2.0.0-beta.9", "mantine-react-table": "2.0.0-beta.9",
@@ -74,7 +74,7 @@
"react": "19.1.0", "react": "19.1.0",
"react-dom": "19.1.0", "react-dom": "19.1.0",
"react-markdown": "^10.1.0", "react-markdown": "^10.1.0",
"recharts": "^2.15.3", "recharts": "^2.15.4",
"video.js": "^8.23.3", "video.js": "^8.23.3",
"zod": "^3.25.67" "zod": "^3.25.67"
}, },
+2
View File
@@ -28,6 +28,7 @@ import * as minecraftServerStatus from "./minecraft/server-status";
import * as networkControllerStatus from "./network-controller/network-status"; import * as networkControllerStatus from "./network-controller/network-status";
import * as networkControllerSummary from "./network-controller/summary"; import * as networkControllerSummary from "./network-controller/summary";
import * as notebook from "./notebook"; import * as notebook from "./notebook";
import * as notifications from "./notifications";
import type { WidgetOptionDefinition } from "./options"; import type { WidgetOptionDefinition } from "./options";
import * as releases from "./releases"; import * as releases from "./releases";
import * as rssFeed from "./rssFeed"; import * as rssFeed from "./rssFeed";
@@ -67,6 +68,7 @@ export const widgetImports = {
minecraftServerStatus, minecraftServerStatus,
dockerContainers, dockerContainers,
releases, releases,
notifications,
} satisfies WidgetImportRecord; } satisfies WidgetImportRecord;
export type WidgetImports = typeof widgetImports; export type WidgetImports = typeof widgetImports;
@@ -252,7 +252,11 @@ function getAvailabilityProperties(
return { color: "blue", label: t("availability.processing") }; return { color: "blue", label: t("availability.processing") };
case MediaAvailability.Pending: case MediaAvailability.Pending:
return { color: "violet", label: t("availability.pending") }; return { color: "violet", label: t("availability.pending") };
case MediaAvailability.Blacklisted:
return { color: "gray", label: t("availability.blacklisted") };
case MediaAvailability.Deleted:
return { color: "red", label: t("availability.deleted") };
default: default:
return { color: "red", label: t("availability.unknown") }; return { color: "orange", label: t("availability.unknown") };
} }
} }
@@ -0,0 +1,106 @@
"use client";
import { useMemo } from "react";
import { Card, Flex, Group, ScrollArea, Stack, Text } from "@mantine/core";
import { IconClock } from "@tabler/icons-react";
import { clientApi } from "@homarr/api/client";
import { useRequiredBoard } from "@homarr/boards/context";
import { useTimeAgo } from "@homarr/common";
import { useScopedI18n } from "@homarr/translation/client";
import type { WidgetComponentProps } from "../definition";
export default function NotificationsWidget({ options, integrationIds }: WidgetComponentProps<"notifications">) {
const [notificationIntegrations] = clientApi.widget.notifications.getNotifications.useSuspenseQuery(
{
...options,
integrationIds,
},
{
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
retry: false,
},
);
const utils = clientApi.useUtils();
clientApi.widget.notifications.subscribeNotifications.useSubscription(
{
...options,
integrationIds,
},
{
onData: (data) => {
utils.widget.notifications.getNotifications.setData({ ...options, integrationIds }, (prevData) => {
return prevData?.map((item) => {
if (item.integration.id !== data.integration.id) return item;
return {
data: data.data,
integration: {
...data.integration,
updatedAt: new Date(),
},
};
});
});
},
},
);
const t = useScopedI18n("widget.notifications");
const board = useRequiredBoard();
const sortedNotifications = useMemo(
() =>
notificationIntegrations
.flatMap((integration) => integration.data)
.sort((entryA, entryB) => entryB.time.getTime() - entryA.time.getTime()),
[notificationIntegrations],
);
return (
<ScrollArea className="scroll-area-w100" w="100%" p="sm">
<Stack w={"100%"} gap="sm">
{sortedNotifications.length > 0 ? (
sortedNotifications.map((notification) => (
<Card key={notification.id} withBorder radius={board.itemRadius} w="100%" p="sm">
<Flex gap="sm" direction="column" w="100%">
{notification.title && (
<Text fz="sm" lh="sm" lineClamp={2}>
{notification.title}
</Text>
)}
<Text c="dimmed" size="sm" lineClamp={4} style={{ whiteSpace: "pre-line" }}>
{notification.body}
</Text>
<InfoDisplay date={notification.time} />
</Flex>
</Card>
))
) : (
<Text size="sm" c="dimmed">
{t("noItems")}
</Text>
)}
</Stack>
</ScrollArea>
);
}
const InfoDisplay = ({ date }: { date: Date }) => {
const timeAgo = useTimeAgo(date, 30000); // update every 30sec
return (
<Group gap={5} align={"center"}>
<IconClock size={"1rem"} color={"var(--mantine-color-dimmed)"} />
<Text size="sm" c="dimmed">
{timeAgo}
</Text>
</Group>
);
};
@@ -0,0 +1,14 @@
import { IconMessage } from "@tabler/icons-react";
import { getIntegrationKindsByCategory } from "@homarr/definitions";
import { createWidgetDefinition } from "../definition";
import { optionsBuilder } from "../options";
export const { componentLoader, definition } = createWidgetDefinition("notifications", {
icon: IconMessage,
createOptions() {
return optionsBuilder.from(() => ({}));
},
supportedIntegrations: getIntegrationKindsByCategory("notifications"),
}).withDynamicImport(() => import("./component"));
+985 -805
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":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?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":"VinnyVynce","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":"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/u/47495914?v=4"},{"login":"bebsworthy","avatar_url":"https://avatars.githubusercontent.com/u/5266759Line 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":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?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":"VinnyVynce","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":"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/u/47495914?v=4"},{"login":"bebsworthy","avatar_url":"https://avatars.githubusercontent.com/u/5266759Line 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":"Skick","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12619811/medium/0331f1de413a645b4516bc4e037f31bb.jpg"},{"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://crowLine 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":"Skick","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12619811/medium/0331f1de413a645b4516bc4e037f31bb.jpg"},{"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://crowLine truncated
+2 -2
View File
@@ -20,11 +20,11 @@
"@next/eslint-plugin-next": "15.3.4", "@next/eslint-plugin-next": "15.3.4",
"eslint-config-prettier": "^10.1.5", "eslint-config-prettier": "^10.1.5",
"eslint-config-turbo": "^2.5.4", "eslint-config-turbo": "^2.5.4",
"eslint-plugin-import": "^2.31.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": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"typescript-eslint": "^8.34.1" "typescript-eslint": "^8.35.0"
}, },
"devDependencies": { "devDependencies": {
"@homarr/prettier-config": "workspace:^0.1.0", "@homarr/prettier-config": "workspace:^0.1.0",
+2 -2
View File
@@ -11,11 +11,11 @@
"prettier": "@homarr/prettier-config", "prettier": "@homarr/prettier-config",
"dependencies": { "dependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.4.2", "@ianvs/prettier-plugin-sort-imports": "^4.4.2",
"prettier": "^3.5.3" "prettier": "^3.6.2"
}, },
"devDependencies": { "devDependencies": {
"@homarr/tsconfig": "workspace:^0.1.0", "@homarr/tsconfig": "workspace:^0.1.0",
"prettier-plugin-packagejson": "^2.5.15", "prettier-plugin-packagejson": "^2.5.16",
"typescript": "^5.8.3" "typescript": "^5.8.3"
} }
} }