chore(release): automatic release v1.32.0

This commit is contained in:
homarr-releases[bot]
2025-08-08 19:15:45 +00:00
committed by GitHub
114 changed files with 3698 additions and 863 deletions

View File

@@ -31,6 +31,7 @@ body:
label: Version
description: What version of Homarr are you running?
options:
- 1.31.0
- 1.30.1
- 1.30.0
- 1.29.0

View File

@@ -60,7 +60,7 @@ jobs:
- uses: actions/setup-node@v4
if: env.SKIP_RELEASE == 'false'
with:
node-version: 22
node-version: 22.18.0
- run: npm i -g pnpm
if: env.SKIP_RELEASE == 'false'
- name: Install dependencies

View File

@@ -0,0 +1,62 @@
name: Update integration list
on:
workflow_dispatch: { }
push:
paths:
- packages/definitions/src/integration.ts
branches:
- dev
permissions:
pull-requests: write
jobs:
update-readme:
concurrency:
group: update-integration
cancel-in-progress: false
runs-on: ubuntu-latest
steps:
- name: Obtain token
id: obtainToken
uses: tibdex/github-app-token@v2
with:
private_key: ${{ secrets.HOMARR_UPDATE_CONTRIBUTORS_PRIVATE_KEY }}
app_id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
- name: Checkout code
uses: actions/checkout@v4
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
- name: Setup
uses: ./tooling/github/setup
- run: pnpm run scripts:update-readme-integrations
- name: Commit changes
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
run: |
git config --global user.email "210161987+homarr-update-contributors[bot]@users.noreply.github.com"
git config --global user.name "Homarr Update Contributors"
git add .
git commit -m "chore: update integrations list readme"
- name: Create Pull Request
id: create-pull-request
uses: peter-evans/create-pull-request@v7
with:
token: ${{ steps.obtainToken.outputs.token }}
branch: update-integrations-readme
base: dev
title: "chore: update integrations list readme"
delete-branch: true
body: |
This PR automatically updates the list of integrations of Homarr in the README.md
- name: Install GitHub CLI
run: sudo apt-get install -y gh
- name: Enable auto-merge
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
run: |
gh pr merge ${{steps.create-pull-request.outputs.pull-request-number}} --auto --squash

View File

@@ -1,4 +1,4 @@
FROM node:22.17.1-alpine AS base
FROM node:22.18.0-alpine AS base
FROM base AS builder
RUN apk add --no-cache libc6-compat

View File

@@ -50,21 +50,21 @@
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0",
"@mantine/colors-generator": "^8.2.2",
"@mantine/core": "^8.2.2",
"@mantine/dropzone": "^8.2.2",
"@mantine/hooks": "^8.2.2",
"@mantine/modals": "^8.2.2",
"@mantine/tiptap": "^8.2.2",
"@mantine/colors-generator": "^8.2.4",
"@mantine/core": "^8.2.4",
"@mantine/dropzone": "^8.2.4",
"@mantine/hooks": "^8.2.4",
"@mantine/modals": "^8.2.4",
"@mantine/tiptap": "^8.2.4",
"@million/lint": "1.0.14",
"@tabler/icons-react": "^3.34.1",
"@tanstack/react-query": "^5.84.1",
"@tanstack/react-query-devtools": "^5.84.1",
"@tanstack/react-query-next-experimental": "^5.84.1",
"@trpc/client": "^11.4.3",
"@trpc/next": "^11.4.3",
"@trpc/react-query": "^11.4.3",
"@trpc/server": "^11.4.3",
"@tanstack/react-query": "^5.84.2",
"@tanstack/react-query-devtools": "^5.84.2",
"@tanstack/react-query-next-experimental": "^5.84.2",
"@trpc/client": "^11.4.4",
"@trpc/next": "^11.4.4",
"@trpc/react-query": "^11.4.4",
"@trpc/server": "^11.4.4",
"@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "^5.5.0",
@@ -74,16 +74,16 @@
"dotenv": "^17.2.1",
"flag-icons": "^7.5.0",
"glob": "^11.0.3",
"jotai": "^2.12.5",
"jotai": "^2.13.0",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.4.5",
"next": "15.4.6",
"postcss-preset-mantine": "^1.18.0",
"prismjs": "^1.30.0",
"react": "19.1.1",
"react-dom": "19.1.1",
"react-error-boundary": "^6.0.0",
"react-simple-code-editor": "^0.14.1",
"sass": "^1.89.2",
"sass": "^1.90.0",
"superjson": "2.2.2",
"swagger-ui-react": "^5.27.1",
"use-deep-compare-effect": "^1.8.1",
@@ -94,7 +94,7 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/chroma-js": "3.1.1",
"@types/node": "^22.17.0",
"@types/node": "^22.17.1",
"@types/prismjs": "^1.26.5",
"@types/react": "19.1.9",
"@types/react-dom": "19.1.7",

View File

@@ -1,37 +1,16 @@
import { Box, Grid, GridCol, Group, Image, Stack, Title } from "@mantine/core";
import { splitToNChunks } from "@homarr/common";
import { integrationDefs } from "@homarr/definitions";
import classes from "./hero-banner.module.css";
const icons = [
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/homarr.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/sabnzbd.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/deluge.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/radarr.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/sonarr.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/lidarr.svg",
"https://cdn.jsdelivr.net/gh/loganmarchione/homelab-svg-assets/assets/pihole.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/dashdot.png",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/overseerr.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/plex.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/jellyfin.svg",
"https://cdn.jsdelivr.net/gh/loganmarchione/homelab-svg-assets/assets/homeassistant.svg",
"https://cdn.jsdelivr.net/gh/loganmarchione/homelab-svg-assets/assets/freshrss.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/readarr.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/transmission.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/qbittorrent.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/nzbget.png",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/openmediavault.svg",
"https://cdn.jsdelivr.net/gh/loganmarchione/homelab-svg-assets/assets/docker.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/jellyseerr.svg",
"https://cdn.jsdelivr.net/gh/loganmarchione/homelab-svg-assets/assets/adguardhome.svg",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/tdarr.png",
"https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/prowlarr.svg",
];
const icons = Object.values(integrationDefs)
.filter((int) => int.name !== "Mock")
.map((int) => int.iconUrl);
const countIconGroups = 3;
const animationDurationInSeconds = 12;
const animationDurationInSeconds = icons.length;
const arrayInChunks = splitToNChunks(icons, countIconGroups);
export const HeroBanner = () => {
@@ -61,12 +40,26 @@ export const HeroBanner = () => {
}}
>
{arrayInChunks[columnIndex]?.map((icon, index) => (
<Image key={`grid-column-${columnIndex}-scroll-1-${index}`} src={icon} radius="md" w={50} h={50} />
<Image
key={`grid-column-${columnIndex}-scroll-1-${index}`}
src={icon}
radius="md"
fit={"contain"}
w={50}
h={50}
/>
))}
{/* This is used for making the animation seem seamless */}
{arrayInChunks[columnIndex]?.map((icon, index) => (
<Image key={`grid-column-${columnIndex}-scroll-2-${index}`} src={icon} radius="md" w={50} h={50} />
<Image
key={`grid-column-${columnIndex}-scroll-2-${index}`}
src={icon}
radius="md"
fit={"contain"}
w={50}
h={50}
/>
))}
</Stack>
</GridCol>

View File

@@ -19,4 +19,6 @@ export const integrationSecretIcons = {
tokenId: IconGrid3x3,
personalAccessToken: IconPasswordUser,
topic: IconMessage,
opnsenseApiKey: IconKey,
opnsenseApiSecret: IconPassword,
} satisfies Record<IntegrationSecretKind, TablerIcon>;

View File

@@ -21,6 +21,12 @@ interface BoardItemContentProps {
item: SectionItem;
}
const getOverflowFromKind = (kind: SectionItem["kind"]) => {
if (kind === "iframe") return "hidden";
if (kind === "systemResources") return "visible";
return undefined;
};
export const BoardItemContent = ({ item }: BoardItemContentProps) => {
const { ref, width, height } = useElementSize<HTMLDivElement>();
const board = useRequiredBoard();
@@ -41,7 +47,7 @@ export const BoardItemContent = ({ item }: BoardItemContentProps) => {
root: {
"--opacity": board.opacity / 100,
containerType: "size",
overflow: item.kind === "iframe" ? "hidden" : undefined,
overflow: getOverflowFromKind(item.kind),
"--border-color": item.advancedOptions.borderColor !== "" ? item.advancedOptions.borderColor : undefined,
},
}}

View File

@@ -45,7 +45,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node": "^22.17.0",
"@types/node": "^22.17.1",
"dotenv-cli": "^10.0.0",
"esbuild": "^0.25.8",
"eslint": "^9.32.0",

View File

@@ -1,5 +1,4 @@
<!-- Project Title -->
[![Banner](./banner.png)](https://homarr.dev/)
![](img/logo/2340450-2-title.png)
<!-- Badges -->
<p align="center">
@@ -20,10 +19,6 @@
<!-- Links -->
<p align="center">
<a href="https://demo.homarr.dev/">
<strong>Demo ✨</strong>
</a>
<a href="https://homarr.dev/docs/category/installation-1/">
<strong>Install 💻</strong>
</a> •
@@ -35,8 +30,7 @@
</a>
</p>
[![Features Section](./section-features.png)](https://homarr.dev/)
![](img/headers/features.png)
- 🖌️ Highly customizable with an extensive drag and drop grid system
- ✨ Integrates seamlessly with your favorite self-hosted applications
@@ -53,44 +47,268 @@
<br/>
<br/>
[![Widgets & Integrations Section](./section-widgets-and-integrations.png)](https://homarr.dev/docs/category/widgets)
![](img/headers/integrations.png)
Homarr has a [built-in collection of widgets and integrations](https://homarr.dev/docs/category/integrations), that connect to your applications and enable you to control them directly from the dashboard.
<!-- AUTO_GENERATE_INTEGRATION_LIST_START -->
- 📥 **Torrent clients**
- [Deluge](https://homarr.dev/docs/integrations/torrent#deluge)
- [Transmission](https://homarr.dev/docs/integrations/torrent#transmission)
- [qBittorent](https://homarr.dev/docs/integrations/torrent#qbittorrent-integration)
- 📥 **Usenet clients**
- [SABnzbd](https://homarr.dev/docs/integrations/usenet#sabnzbd)
- [NZBGet](https://homarr.dev/docs/integrations/usenet#nzbget)
- 📺 **Media servers**
- [Plex](https://homarr.dev/docs/integrations/media-server/#plex)
- [Jellyfin](https://homarr.dev/docs/integrations/media-server#jellyfin-and-emby)
- 📚 **Media collection managers**
- [Sonarr](https://homarr.dev/docs/integrations/servarr#sonarr)
- [Radarr](https://homarr.dev/docs/integrations/servarr#radarr)
- [Lidarr](https://homarr.dev/docs/integrations/servarr#lidarr)
- [Readarr](https://homarr.dev/docs/integrations/servarr#readarr)
- 🎞️ **Media request managers**
- [Overseerr](https://homarr.dev/docs/integrations/media-requester)
- [Jellyseerr](https://homarr.dev/docs/integrations/media-requester)
- 🚫 **DNS ad-blockers**
- [Pihole](https://homarr.dev/docs/integrations/dns#pihole)
- [AdGuard Home](https://homarr.dev/docs/integrations/dns#adguard-home)
- 🖥️ **Monitoring**
- [Dash.](https://homarr.dev/docs/integrations/hardware)
- [OpenMediaVault.](https://homarr.dev/docs/integrations/hardware/#openmediavault)
- [Proxmox.](https://homarr.dev/docs/integrations/hardware/#proxmox)
- 🐳 **Container management**:
- [Docker](https://homarr.dev/docs/integrations/containers)
<div align="center">
<table>
<tbody>
<tr><td align="center">
<a href="https://homarr.dev/docs/integrations/adguard-home" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/adguard-home.svg" alt="AdGuard Home" width="90" height="90" />
<br/>
<p align="center">AdGuard<br/>Home</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/aria2" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/PapirusDevelopmentTeam/papirus_icons@latest/src/system_downloads_3.svg" alt="Aria2" width="90" height="90" />
<br/>
<p align="center">Aria2</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/codeberg" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/codeberg.svg" alt="Codeberg" width="90" height="90" />
<br/>
<p align="center">Codeberg</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/dash-dot" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/dashdot.png" alt="Dash." width="90" height="90" />
<br/>
<p align="center">Dash.</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/deluge" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/deluge.svg" alt="Deluge" width="90" height="90" />
<br/>
<p align="center">Deluge</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/docker-hub" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/docker.svg" alt="Docker Hub" width="90" height="90" />
<br/>
<p align="center">Docker<br/>Hub</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/emby" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/emby.svg" alt="Emby" width="90" height="90" />
<br/>
<p align="center">Emby</p>
</a>
</td></tr>
<tr><td align="center">
<a href="https://homarr.dev/docs/integrations/github" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/github.svg" alt="Github" width="90" height="90" />
<br/>
<p align="center">Github</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/github" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/github.svg" alt="GitHub Container Registry" width="90" height="90" />
<br/>
<p align="center">GitHub<br/>Container<br/>Registry</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/gitlab" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/gitlab.svg" alt="Gitlab" width="90" height="90" />
<br/>
<p align="center">Gitlab</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/home-assistant" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/home-assistant.svg" alt="Home Assistant" width="90" height="90" />
<br/>
<p align="center">Home<br/>Assistant</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/jellyfin" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/jellyfin.svg" alt="Jellyfin" width="90" height="90" />
<br/>
<p align="center">Jellyfin</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/jellyseerr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/jellyseerr.svg" alt="Jellyseerr" width="90" height="90" />
<br/>
<p align="center">Jellyseerr</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/lidarr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/lidarr.svg" alt="Lidarr" width="90" height="90" />
<br/>
<p align="center">Lidarr</p>
</a>
</td></tr>
<tr><td align="center">
<a href="https://homarr.dev/docs/integrations/linux-server-io" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/linuxserver-io.svg" alt="LinuxServer.io" width="90" height="90" />
<br/>
<p align="center">LinuxServer.io</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/nextcloud" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/nextcloud.svg" alt="Nextcloud" width="90" height="90" />
<br/>
<p align="center">Nextcloud</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/npm" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/npm.svg" alt="NPM" width="90" height="90" />
<br/>
<p align="center">NPM</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/ntfy" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/ntfy.svg" alt="ntfy" width="90" height="90" />
<br/>
<p align="center">ntfy</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/nzbget" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/nzbget.svg" alt="NZBGet" width="90" height="90" />
<br/>
<p align="center">NZBGet</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/open-media-vault" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/openmediavault.svg" alt="OpenMediaVault" width="90" height="90" />
<br/>
<p align="center">OpenMediaVault</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/opnsense" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/opnsense.svg" alt="OPNsense" width="90" height="90" />
<br/>
<p align="center">OPNsense</p>
</a>
</td></tr>
<tr><td align="center">
<a href="https://homarr.dev/docs/integrations/overseerr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/overseerr.svg" alt="Overseerr" width="90" height="90" />
<br/>
<p align="center">Overseerr</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/pi-hole" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/pi-hole.svg" alt="Pi-hole" width="90" height="90" />
<br/>
<p align="center">Pi-hole</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/plex" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/plex.svg" alt="Plex" width="90" height="90" />
<br/>
<p align="center">Plex</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/prowlarr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/prowlarr.svg" alt="Prowlarr" width="90" height="90" />
<br/>
<p align="center">Prowlarr</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/proxmox" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/proxmox.svg" alt="Proxmox" width="90" height="90" />
<br/>
<p align="center">Proxmox</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/q-bittorent" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/qbittorrent.svg" alt="qBittorrent" width="90" height="90" />
<br/>
<p align="center">qBittorrent</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/quay" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/quay.png" alt="Quay" width="90" height="90" />
<br/>
<p align="center">Quay</p>
</a>
</td></tr>
<tr><td align="center">
<a href="https://homarr.dev/docs/integrations/radarr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/radarr.svg" alt="Radarr" width="90" height="90" />
<br/>
<p align="center">Radarr</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/readarr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/readarr.svg" alt="Readarr" width="90" height="90" />
<br/>
<p align="center">Readarr</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/sabnzbd" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/sabnzbd.svg" alt="SABnzbd" width="90" height="90" />
<br/>
<p align="center">SABnzbd</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/sonarr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/sonarr.svg" alt="Sonarr" width="90" height="90" />
<br/>
<p align="center">Sonarr</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/tdarr" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/tdarr.png" alt="Tdarr" width="90" height="90" />
<br/>
<p align="center">Tdarr</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/transmission" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/transmission.svg" alt="Transmission" width="90" height="90" />
<br/>
<p align="center">Transmission</p>
</a>
</td>
<td align="center">
<a href="https://homarr.dev/docs/integrations/unifi-controller" target="_blank" rel="noreferrer noopener">
<img src="https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/unifi.png" alt="Unifi Controller" width="90" height="90" />
<br/>
<p align="center">Unifi<br/>Controller</p>
</a>
</td></tr>
</tbody>
</table>
</div>
<!-- AUTO_GENERATE_INTEGRATION_LIST_END -->
<br/>
<br/>
[![Installation Section](./section-installation.png)](https://homarr.dev/docs/category/installation-1)
Since we are updating Homarr very frequently, we recommend reading our official installation guides:
![](img/headers/installation.png)
<h2>
<a href="https://homarr.dev/docs/category/installation-1/">
@@ -101,12 +319,15 @@ Since we are updating Homarr very frequently, we recommend reading our official
<br/>
<br/>
[![Contribute Section](./section-contribute.png)](https://opencollective.com/homarr)
![](img/headers/contribute.png)
<br/>
Homarr is a free to use open source project that is maintained by volunteers and developers from all over the world. We publish under the ``Apache License 2.0`` license which allows commercial usage. We invest multiple hours daily in to providing support, developing Homarr, integrating to third party software and more. We also pay for licensing and server hosting fees.
Please consider to help us cover these costs to enable the future development of Homarr. Thank you!
Homarr is a free-to-use open source project maintained by volunteers and developers from all over the world.
We publish under the `Apache License 2.0` license which allows commercial usage.
We invest multiple hours daily in providing support, developing Homarr, integrating to third party software and more.
We also pay for licensing and server hosting fees.
Please consider helping us cover these costs to enable the future development of Homarr. Thank you!
<h2>
<a href="https://opencollective.com/homarr">
@@ -117,9 +338,9 @@ Please consider to help us cover these costs to enable the future development of
You can also support us by helping with [translating the entire project](https://homarr.dev/docs/community/translations) to as many languages as possible or contributing directly to the code or documentation. Please read our [Contribution Guidelines](/CONTRIBUTING.md). All contributions, regardless of their size or scope, are welcome and highly appreciated! Thank you ❤️
## Sponsors
Thanks to your generous sponsors we can continue to build Homarr. Check them out for high quality and easy to use development tools.
Thanks to your generous sponsors, we can continue to build Homarr. Check them out for high-quality and easy-to-use development tools.
Feel free to contact us at homarr-labs@proton.me if you wish to become a sponsor.
[![Covered by Argos Visual Testing](https://argos-ci.com/badge-large.svg)](https://argos-ci.com?utm_source=%5Bhomarr%5D&utm_campaign=oss) \
[![Supported by PikaPods](https://www.pikapods.com/static/run-button.svg)](https://www.pikapods.com/pods?run=homarr-v1)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
docs/img/headers/header.xcf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

View File

@@ -27,7 +27,8 @@
"test:e2e": "cross-env NODE_ENV=development CI=true vitest e2e",
"test:ui": "cross-env NODE_ENV=development CI=true vitest --exclude e2e --ui --coverage.enabled",
"typecheck": "turbo typecheck",
"with-env": "dotenv -e .env --"
"with-env": "dotenv -e .env --",
"scripts:update-readme-integrations": "tsx ./scripts/update-integration-list.mts"
},
"prettier": "@homarr/prettier-config",
"devDependencies": {
@@ -38,7 +39,7 @@
"@semantic-release/github": "^11.0.3",
"@semantic-release/npm": "^12.0.2",
"@semantic-release/release-notes-generator": "^14.0.3",
"@testcontainers/redis": "^11.4.0",
"@testcontainers/redis": "^11.5.1",
"@turbo/gen": "^2.5.5",
"@vitejs/plugin-react": "^4.7.0",
"@vitest/coverage-v8": "^3.2.4",
@@ -48,7 +49,7 @@
"jsdom": "^26.1.0",
"prettier": "^3.6.2",
"semantic-release": "^24.2.7",
"testcontainers": "^11.4.0",
"testcontainers": "^11.5.1",
"turbo": "^2.5.5",
"typescript": "^5.9.2",
"vite-tsconfig-paths": "^5.1.4",

View File

@@ -41,17 +41,17 @@
"@homarr/server-settings": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@kubernetes/client-node": "^1.3.0",
"@tanstack/react-query": "^5.84.1",
"@trpc/client": "^11.4.3",
"@trpc/react-query": "^11.4.3",
"@trpc/server": "^11.4.3",
"@trpc/tanstack-react-query": "^11.4.3",
"@tanstack/react-query": "^5.84.2",
"@trpc/client": "^11.4.4",
"@trpc/react-query": "^11.4.4",
"@trpc/server": "^11.4.4",
"@trpc/tanstack-react-query": "^11.4.4",
"lodash.clonedeep": "^4.5.0",
"next": "15.4.5",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1",
"superjson": "2.2.2",
"trpc-to-openapi": "^2.3.2",
"trpc-to-openapi": "^2.4.0",
"zod": "^3.25.76"
},
"devDependencies": {

View File

@@ -8,6 +8,7 @@ import { groupRouter } from "./router/group";
import { homeRouter } from "./router/home";
import { iconsRouter } from "./router/icons";
import { importRouter } from "./router/import/import-router";
import { infoRouter } from "./router/info";
import { integrationRouter } from "./router/integration/integration-router";
import { inviteRouter } from "./router/invite";
import { kubernetesRouter } from "./router/kubernetes/router/kubernetes-router";
@@ -47,6 +48,7 @@ export const appRouter = createTRPCRouter({
media: mediaRouter,
updateChecker: updateCheckerRouter,
certificates: certificateRouter,
info: infoRouter,
});
// export type definition of API

View File

@@ -277,12 +277,14 @@ export const groupRouter = createTRPCRouter({
await ctx.db.delete(groupPermissions).where(eq(groupPermissions.groupId, input.groupId));
await ctx.db.insert(groupPermissions).values(
input.permissions.map((permission) => ({
groupId: input.groupId,
permission,
})),
);
if (input.permissions.length > 0) {
await ctx.db.insert(groupPermissions).values(
input.permissions.map((permission) => ({
groupId: input.groupId,
permission,
})),
);
}
}),
transferOwnership: permissionRequiredProcedure
.requiresPermission("admin")

View File

@@ -0,0 +1,16 @@
import z from "zod";
import packageJson from "../../../../package.json";
import { createTRPCRouter, protectedProcedure } from "../trpc";
export const infoRouter = createTRPCRouter({
getInfo: protectedProcedure
.input(z.void())
.output(z.object({ version: z.string() }))
.meta({ openapi: { method: "GET", path: "/api/info", tags: ["info"] } })
.query(() => {
return {
version: packageJson.version,
};
}),
});

View File

@@ -35,7 +35,7 @@
"bcrypt": "^6.0.0",
"cookies": "^0.9.1",
"ldapts": "8.0.9",
"next": "15.4.5",
"next": "15.4.6",
"next-auth": "5.0.0-beta.29",
"react": "19.1.1",
"react-dom": "19.1.1",

View File

@@ -31,7 +31,7 @@
"@homarr/log": "workspace:^0.1.0",
"@paralleldrive/cuid2": "^2.2.2",
"dayjs": "^1.11.13",
"next": "15.4.5",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1",
"undici": "7.13.0",

View File

@@ -29,10 +29,10 @@
"@homarr/core": "workspace:^0.1.0",
"@homarr/cron-jobs": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@tanstack/react-query": "^5.84.1",
"@trpc/client": "^11.4.3",
"@trpc/server": "^11.4.3",
"@trpc/tanstack-react-query": "^11.4.3",
"@tanstack/react-query": "^5.84.2",
"@trpc/client": "^11.4.4",
"@trpc/server": "^11.4.4",
"@trpc/tanstack-react-query": "^11.4.4",
"node-cron": "^4.2.1",
"react": "19.1.1",
"zod": "^3.25.76"

View File

@@ -15,9 +15,10 @@ export const healthMonitoringJob = createCronJob("healthMonitoring", EVERY_5_SEC
return clusterInfoRequestHandler.handler({ ...integration, kind }, itemOptions);
},
{
widgetKinds: ["healthMonitoring"],
widgetKinds: ["healthMonitoring", "systemResources"],
getInput: {
healthMonitoring: () => ({}),
systemResources: () => ({}),
},
},
),

View File

@@ -0,0 +1,52 @@
import type { Database } from "../..";
import { and, eq } from "../..";
import { integrationSecrets } from "../../schema";
/**
* Previously the credentials for OPNsense were stored as username and password.
* However it should have been the api key and secret.
* For more information see:
* https://docs.opnsense.org/development/how-tos/api.html#creating-keys
*/
export async function migrateOpnsenseCredentialsAsync(db: Database) {
const existingIntegrations = await db.query.integrations.findMany({
where: (table, { eq }) => eq(table.kind, "opnsense"),
with: {
secrets: true,
},
});
await Promise.all(
existingIntegrations.map(async (integration) => {
const username = integration.secrets.find((secret) => secret.kind === "username");
if (!username) return;
await db
.update(integrationSecrets)
.set({
kind: "opnsenseApiKey",
})
.where(
and(eq(integrationSecrets.integrationId, username.integrationId), eq(integrationSecrets.kind, "username")),
);
}),
);
await Promise.all(
existingIntegrations.map(async (integration) => {
const password = integration.secrets.find((secret) => secret.kind === "password");
if (!password) return;
await db
.update(integrationSecrets)
.set({
kind: "opnsenseApiSecret",
})
.where(
and(eq(integrationSecrets.integrationId, password.integrationId), eq(integrationSecrets.kind, "password")),
);
}),
);
if (existingIntegrations.length > 0) {
console.log(`Migrated OPNsense credentials count="${existingIntegrations.length}"`);
}
}

View File

@@ -1,6 +1,8 @@
import type { Database } from "../..";
import { migrateReleaseWidgetProviderToOptionsAsync } from "./0000_release_widget_provider_to_options";
import { migrateOpnsenseCredentialsAsync } from "./0001_opnsense_credentials";
export const applyCustomMigrationsAsync = async (db: Database) => {
await migrateReleaseWidgetProviderToOptionsAsync(db);
await migrateOpnsenseCredentialsAsync(db);
};

View File

@@ -44,9 +44,9 @@
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/core": "^8.2.2",
"@mantine/core": "^8.2.4",
"@paralleldrive/cuid2": "^2.2.2",
"@testcontainers/mysql": "^11.4.0",
"@testcontainers/mysql": "^11.5.1",
"better-sqlite3": "^12.2.0",
"dotenv": "^17.2.1",
"drizzle-kit": "^0.31.4",

View File

@@ -9,8 +9,8 @@ export type HomarrDocumentationPath =
| "/blog/2023/12/22/updated-documentation"
| "/blog/2024/09/23/version-1.0"
| "/blog/2024/12/17/open-beta-1.0"
| "/blog/2024/12/31/migrate-secret-enryption-key"
| "/blog/2025/01/19/migration-guide-1.0"
| "/blog/2025/08/02/using-argus"
| "/blog/archive"
| "/blog/authors"
| "/blog/authors/ajnart"
@@ -148,12 +148,14 @@ export type HomarrDocumentationPath =
| "/docs/getting-started/installation/synology"
| "/docs/getting-started/installation/unraid"
| "/docs/integrations/adguard-home"
| "/docs/integrations/aria2"
| "/docs/integrations/codeberg"
| "/docs/integrations/dash-dot"
| "/docs/integrations/deluge"
| "/docs/integrations/docker-hub"
| "/docs/integrations/docker"
| "/docs/integrations/emby"
| "/docs/integrations/github-containerregistry"
| "/docs/integrations/github"
| "/docs/integrations/gitlab"
| "/docs/integrations/home-assistant"
@@ -161,17 +163,20 @@ export type HomarrDocumentationPath =
| "/docs/integrations/jellyseerr"
| "/docs/integrations/kubernetes"
| "/docs/integrations/lidarr"
| "/docs/integrations/linux-server-io"
| "/docs/integrations/nextcloud"
| "/docs/integrations/npm"
| "/docs/integrations/ntfy"
| "/docs/integrations/nzbget"
| "/docs/integrations/open-media-vault"
| "/docs/integrations/opnsense"
| "/docs/integrations/overseerr"
| "/docs/integrations/pi-hole"
| "/docs/integrations/plex"
| "/docs/integrations/prowlarr"
| "/docs/integrations/proxmox"
| "/docs/integrations/q-bittorent"
| "/docs/integrations/quay"
| "/docs/integrations/radarr"
| "/docs/integrations/readarr"
| "/docs/integrations/sabnzbd"
@@ -197,6 +202,7 @@ export type HomarrDocumentationPath =
| "/docs/widgets/dns-hole-summary"
| "/docs/widgets/docker-containers"
| "/docs/widgets/downloads"
| "/docs/widgets/firewall"
| "/docs/widgets/health-monitoring"
| "/docs/widgets/iframe"
| "/docs/widgets/indexer-manager"

View File

@@ -1,6 +1,8 @@
import { objectKeys } from "@homarr/common";
import type { AtLeastOneOf } from "@homarr/common/types";
import { createDocumentationLink } from "./docs";
export const integrationSecretKindObject = {
apiKey: { isPublic: false },
username: { isPublic: true },
@@ -9,6 +11,8 @@ export const integrationSecretKindObject = {
realm: { isPublic: true },
personalAccessToken: { isPublic: false },
topic: { isPublic: true },
opnsenseApiKey: { isPublic: false },
opnsenseApiSecret: { isPublic: false },
} satisfies Record<string, { isPublic: boolean }>;
export const integrationSecretKinds = objectKeys(integrationSecretKindObject);
@@ -18,6 +22,7 @@ interface integrationDefinition {
iconUrl: string;
secretKinds: AtLeastOneOf<IntegrationSecretKind[]>; // at least one secret kind set is required
category: AtLeastOneOf<IntegrationCategory>;
documentationUrl: string | null;
defaultUrl?: string; // optional default URL for the integration
}
@@ -27,156 +32,182 @@ export const integrationDefs = {
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/sabnzbd.svg",
category: ["downloadClient", "usenet"],
documentationUrl: createDocumentationLink("/docs/integrations/sabnzbd"),
},
nzbGet: {
name: "NZBGet",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/nzbget.svg",
category: ["downloadClient", "usenet"],
documentationUrl: createDocumentationLink("/docs/integrations/nzbget"),
},
deluge: {
name: "Deluge",
secretKinds: [["password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/deluge.svg",
category: ["downloadClient", "torrent"],
documentationUrl: createDocumentationLink("/docs/integrations/deluge"),
},
transmission: {
name: "Transmission",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/transmission.svg",
category: ["downloadClient", "torrent"],
documentationUrl: createDocumentationLink("/docs/integrations/transmission"),
},
qBittorrent: {
name: "qBittorrent",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/qbittorrent.svg",
category: ["downloadClient", "torrent"],
documentationUrl: createDocumentationLink("/docs/integrations/q-bittorent"),
},
aria2: {
name: "Aria2",
secretKinds: [[], ["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/PapirusDevelopmentTeam/papirus_icons@latest/src/system_downloads_3.svg",
category: ["downloadClient", "torrent", "miscellaneous"],
documentationUrl: createDocumentationLink("/docs/integrations/aria2"),
},
sonarr: {
name: "Sonarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/sonarr.svg",
category: ["calendar"],
documentationUrl: createDocumentationLink("/docs/integrations/sonarr"),
},
radarr: {
name: "Radarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/radarr.svg",
category: ["calendar"],
documentationUrl: createDocumentationLink("/docs/integrations/radarr"),
},
lidarr: {
name: "Lidarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/lidarr.svg",
category: ["calendar"],
documentationUrl: createDocumentationLink("/docs/integrations/lidarr"),
},
readarr: {
name: "Readarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/readarr.svg",
category: ["calendar"],
documentationUrl: createDocumentationLink("/docs/integrations/readarr"),
},
prowlarr: {
name: "Prowlarr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/prowlarr.svg",
category: ["indexerManager"],
documentationUrl: createDocumentationLink("/docs/integrations/prowlarr"),
},
jellyfin: {
name: "Jellyfin",
secretKinds: [["username", "password"], ["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/jellyfin.svg",
category: ["mediaService", "mediaRelease"],
documentationUrl: createDocumentationLink("/docs/integrations/jellyfin"),
},
emby: {
name: "Emby",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/emby.svg",
category: ["mediaService", "mediaRelease"],
documentationUrl: createDocumentationLink("/docs/integrations/emby"),
},
plex: {
name: "Plex",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/plex.svg",
category: ["mediaService", "mediaRelease"],
documentationUrl: createDocumentationLink("/docs/integrations/plex"),
},
jellyseerr: {
name: "Jellyseerr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/jellyseerr.svg",
category: ["mediaSearch", "mediaRequest", "search"],
documentationUrl: createDocumentationLink("/docs/integrations/jellyseerr"),
},
overseerr: {
name: "Overseerr",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/overseerr.svg",
category: ["mediaSearch", "mediaRequest", "search"],
documentationUrl: createDocumentationLink("/docs/integrations/overseerr"),
},
piHole: {
name: "Pi-hole",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/pi-hole.svg",
category: ["dnsHole"],
documentationUrl: createDocumentationLink("/docs/integrations/pi-hole"),
},
adGuardHome: {
name: "AdGuard Home",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/adguard-home.svg",
category: ["dnsHole"],
documentationUrl: createDocumentationLink("/docs/integrations/adguard-home"),
},
homeAssistant: {
name: "Home Assistant",
secretKinds: [["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/home-assistant.svg",
category: ["smartHomeServer"],
documentationUrl: createDocumentationLink("/docs/integrations/home-assistant"),
},
openmediavault: {
name: "OpenMediaVault",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/openmediavault.svg",
category: ["healthMonitoring"],
documentationUrl: createDocumentationLink("/docs/integrations/open-media-vault"),
},
dashDot: {
name: "Dash.",
secretKinds: [[]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/dashdot.png",
category: ["healthMonitoring"],
documentationUrl: createDocumentationLink("/docs/integrations/dash-dot"),
},
tdarr: {
name: "Tdarr",
secretKinds: [[], ["apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/tdarr.png",
category: ["mediaTranscoding"],
documentationUrl: createDocumentationLink("/docs/integrations/tdarr"),
},
proxmox: {
name: "Proxmox",
secretKinds: [["username", "tokenId", "apiKey", "realm"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/proxmox.svg",
category: ["healthMonitoring"],
documentationUrl: createDocumentationLink("/docs/integrations/proxmox"),
},
nextcloud: {
name: "Nextcloud",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/nextcloud.svg",
category: ["calendar"],
documentationUrl: createDocumentationLink("/docs/integrations/nextcloud"),
},
unifiController: {
name: "Unifi Controller",
secretKinds: [["username", "password"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/unifi.png",
category: ["networkController"],
documentationUrl: createDocumentationLink("/docs/integrations/unifi-controller"),
},
opnsense: {
name: "OPNsense",
secretKinds: [["username", "password"]],
secretKinds: [["opnsenseApiKey", "opnsenseApiSecret"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/opnsense.svg",
category: ["firewall"],
documentationUrl: createDocumentationLink("/docs/integrations/opnsense"),
},
github: {
name: "Github",
@@ -184,6 +215,7 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/github.svg",
category: ["releasesProvider"],
defaultUrl: "https://api.github.com",
documentationUrl: createDocumentationLink("/docs/integrations/github"),
},
dockerHub: {
name: "Docker Hub",
@@ -191,6 +223,7 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/docker.svg",
category: ["releasesProvider"],
defaultUrl: "https://hub.docker.com",
documentationUrl: createDocumentationLink("/docs/integrations/docker-hub"),
},
gitlab: {
name: "Gitlab",
@@ -198,6 +231,7 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/gitlab.svg",
category: ["releasesProvider"],
defaultUrl: "https://gitlab.com",
documentationUrl: createDocumentationLink("/docs/integrations/gitlab"),
},
npm: {
name: "NPM",
@@ -205,6 +239,7 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/npm.svg",
category: ["releasesProvider"],
defaultUrl: "https://registry.npmjs.org",
documentationUrl: createDocumentationLink("/docs/integrations/npm"),
},
codeberg: {
name: "Codeberg",
@@ -212,6 +247,7 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/codeberg.svg",
category: ["releasesProvider"],
defaultUrl: "https://codeberg.org",
documentationUrl: createDocumentationLink("/docs/integrations/codeberg"),
},
linuxServerIO: {
name: "LinuxServer.io",
@@ -219,6 +255,7 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/linuxserver-io.svg",
category: ["releasesProvider"],
defaultUrl: "https://api.linuxserver.io",
documentationUrl: createDocumentationLink("/docs/integrations/linux-server-io"),
},
gitHubContainerRegistry: {
name: "GitHub Container Registry",
@@ -226,6 +263,7 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/github.svg",
category: ["releasesProvider"],
defaultUrl: "https://api.github.com",
documentationUrl: createDocumentationLink("/docs/integrations/github"),
},
quay: {
name: "Quay",
@@ -233,12 +271,14 @@ export const integrationDefs = {
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/png/quay.png",
category: ["releasesProvider"],
defaultUrl: "https://quay.io",
documentationUrl: createDocumentationLink("/docs/integrations/quay"),
},
ntfy: {
name: "ntfy",
secretKinds: [["topic"], ["topic", "apiKey"]],
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/ntfy.svg",
category: ["notifications"],
documentationUrl: createDocumentationLink("/docs/integrations/ntfy"),
},
// This integration only returns mock data, it is used during development (but can also be used in production by directly going to the create page)
mock: {
@@ -259,6 +299,7 @@ export const integrationDefs = {
"notifications",
"smartHomeServer",
],
documentationUrl: null,
},
} as const satisfies Record<string, integrationDefinition>;

View File

@@ -28,5 +28,6 @@ export const widgetKinds = [
"dockerContainers",
"firewall",
"notifications",
"systemResources",
] as const;
export type WidgetKind = (typeof widgetKinds)[number];

View File

@@ -26,7 +26,7 @@
"@homarr/common": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/form": "^8.2.2",
"@mantine/form": "^8.2.4",
"zod": "^3.25.76"
},
"devDependencies": {

View File

@@ -29,7 +29,7 @@
"@homarr/notifications": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.2.2",
"@mantine/core": "^8.2.4",
"react": "19.1.1",
"zod": "^3.25.76"
},

View File

@@ -28,7 +28,7 @@
"@ctrl/deluge": "^7.1.1",
"@ctrl/qbittorrent": "^9.6.0",
"@ctrl/transmission": "^7.2.0",
"@gitbeaker/rest": "^43.3.0",
"@gitbeaker/rest": "^43.4.0",
"@homarr/certificates": "workspace:^0.1.0",
"@homarr/common": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",

View File

@@ -3,8 +3,10 @@ import { logger } from "@homarr/log";
import type { Integration } from "../integration";
import type { IIntegrationErrorHandler } from "./handler";
import { integrationFetchHttpErrorHandler } from "./http";
import { IntegrationError } from "./integration-error";
import { IntegrationUnknownError } from "./integration-unknown-error";
import { integrationJsonParseErrorHandler, integrationZodParseErrorHandler } from "./parse";
const localLogger = logger.child({
module: "HandleIntegrationErrors",
@@ -13,7 +15,14 @@ const localLogger = logger.child({
// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-explicit-any
type AbstractConstructor<T = {}> = abstract new (...args: any[]) => T;
const defaultErrorHandlers: IIntegrationErrorHandler[] = [
integrationZodParseErrorHandler,
integrationJsonParseErrorHandler,
integrationFetchHttpErrorHandler,
];
export const HandleIntegrationErrors = (errorHandlers: IIntegrationErrorHandler[]) => {
const combinedErrorHandlers = [...defaultErrorHandlers, ...errorHandlers];
return <T extends AbstractConstructor<Integration>>(IntegrationBaseClass: T): T => {
abstract class ErrorHandledIntegration extends IntegrationBaseClass {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -42,7 +51,7 @@ export const HandleIntegrationErrors = (errorHandlers: IIntegrationErrorHandler[
throw error;
}
for (const handler of errorHandlers) {
for (const handler of combinedErrorHandlers) {
const handledError = handler.handleError(error, this.publicIntegration);
if (!handledError) continue;

View File

@@ -8,8 +8,6 @@ import { removeTrailingSlash } from "@homarr/common";
import type { IntegrationSecretKind } from "@homarr/definitions";
import { HandleIntegrationErrors } from "./errors/decorator";
import { integrationFetchHttpErrorHandler } from "./errors/http";
import { integrationJsonParseErrorHandler, integrationZodParseErrorHandler } from "./errors/parse";
import { TestConnectionError } from "./test-connection/test-connection-error";
import type { TestingResult } from "./test-connection/test-connection-service";
import { TestConnectionService } from "./test-connection/test-connection-service";
@@ -32,11 +30,7 @@ export interface IntegrationTestingInput {
};
}
@HandleIntegrationErrors([
integrationZodParseErrorHandler,
integrationJsonParseErrorHandler,
integrationFetchHttpErrorHandler,
])
@HandleIntegrationErrors([])
export abstract class Integration {
constructor(protected integration: IntegrationInput) {}

View File

@@ -7,7 +7,7 @@ import { z } from "zod";
import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
import { createChannelEventHistory } from "../../../redis/src/lib/channel";
import { createChannelEventHistoryOld } from "../../../redis/src/lib/channel";
import type { IntegrationTestingInput } from "../base/integration";
import { Integration } from "../base/integration";
import { TestConnectionError } from "../base/test-connection/test-connection-error";
@@ -32,14 +32,16 @@ export class DashDotIntegration extends Integration implements ISystemHealthMoni
const cpuLoad = await this.getCurrentCpuLoadAsync();
const memoryLoad = await this.getCurrentMemoryLoadAsync();
const storageLoad = await this.getCurrentStorageLoadAsync();
const networkLoad = await this.getCurrentNetworkLoadAsync();
const channel = this.getChannel();
const history = await channel.getSliceUntilTimeAsync(dayjs().subtract(15, "minutes").toDate());
return {
cpuUtilization: cpuLoad.sumLoad,
memUsed: `${memoryLoad.loadInBytes}`,
memAvailable: `${info.maxAvailableMemoryBytes - memoryLoad.loadInBytes}`,
memUsedInBytes: memoryLoad.loadInBytes,
memAvailableInBytes: info.maxAvailableMemoryBytes - memoryLoad.loadInBytes,
network: networkLoad,
fileSystem: info.storage
.filter((_, index) => storageLoad[index] !== -1) // filter out undermoutned drives, they display as -1 in the load API
.map((storage, index) => ({
@@ -113,8 +115,13 @@ export class DashDotIntegration extends Integration implements ISystemHealthMoni
};
}
private async getCurrentNetworkLoadAsync() {
const response = await fetchWithTrustedCertificatesAsync(this.url("/load/network"));
return await networkLoadApi.parseAsync(await response.json());
}
private getChannel() {
return createChannelEventHistory<z.infer<typeof cpuLoadPerCoreApiList>>(
return createChannelEventHistoryOld<z.infer<typeof cpuLoadPerCoreApiList>>(
`integration:${this.integration.id}:history:cpu`,
100,
);
@@ -130,6 +137,11 @@ const memoryLoadApi = z.object({
load: z.number().min(0),
});
const networkLoadApi = z.object({
up: z.number().min(0),
down: z.number().min(0),
});
const internalServerInfoApi = z.object({
os: z.object({
distro: z.string(),

View File

@@ -4,9 +4,13 @@ export interface SystemHealthMonitoring {
version: string;
cpuModelName: string;
cpuUtilization: number;
memUsed: string;
memAvailable: string;
memUsedInBytes: number;
memAvailableInBytes: number;
uptime: number;
network: {
up: number;
down: number;
} | null;
loadAverage: {
"1min": number;
"5min": number;

View File

@@ -7,9 +7,13 @@ export class SystemHealthMonitoringMockService implements ISystemHealthMonitorin
version: "1.0.0",
cpuModelName: "Mock CPU",
cpuUtilization: Math.random(),
memUsed: (4 * 1024 * 1024 * 1024).toString(), // 4 GB in bytes
memAvailable: (8 * 1024 * 1024 * 1024).toString(), // 8 GB in bytes
memUsedInBytes: 4 * 1024 * 1024 * 1024, // 4 GB in bytes
memAvailableInBytes: 8 * 1024 * 1024 * 1024, // 8 GB in bytes
availablePkgUpdates: 0,
network: {
up: 1024 * 16,
down: 1024 * 16 * 6,
},
rebootRequired: false,
cpuTemp: Math.floor(Math.random() * 100), // Random temperature between 0 and 99
uptime: Math.floor(Math.random() * 1000000), // Random uptime in seconds

View File

@@ -69,9 +69,11 @@ export class OpenMediaVaultIntegration extends Integration implements ISystemHea
version: systemResult.data.response.version,
cpuModelName: systemResult.data.response.cpuModelName ?? "Unknown CPU",
cpuUtilization: systemResult.data.response.cpuUtilization,
memUsed: systemResult.data.response.memUsed,
memAvailable: systemResult.data.response.memAvailable,
memUsedInBytes: Number(systemResult.data.response.memUsed),
memAvailableInBytes: Number(systemResult.data.response.memAvailable),
uptime: systemResult.data.response.uptime,
/* real-time traffic monitoring is not available over the RPC API from OMV */
network: null,
loadAverage: {
"1min": systemResult.data.response.loadAverage["1min"],
"5min": systemResult.data.response.loadAverage["5min"],

View File

@@ -1,8 +1,7 @@
import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
import { ParseError, ResponseError } from "@homarr/common/server";
import { createChannelEventHistory } from "@homarr/redis";
import { HandleIntegrationErrors } from "../base/errors/decorator";
import { createChannelEventHistoryOld } from "../../../redis/src/lib/channel";
import type { IntegrationTestingInput } from "../base/integration";
import { Integration } from "../base/integration";
import { TestConnectionError } from "../base/test-connection/test-connection-error";
@@ -22,7 +21,6 @@ import {
opnsenseSystemSummarySchema,
} from "./opnsense-types";
@HandleIntegrationErrors([])
export class OPNsenseIntegration extends Integration implements FirewallSummaryIntegration {
protected async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
const response = await input.fetchAsync(this.url("/api/diagnostics/system/system_information"), {
@@ -39,9 +37,9 @@ export class OPNsenseIntegration extends Integration implements FirewallSummaryI
}
private getAuthHeaders() {
const username = super.getSecretValue("username");
const password = super.getSecretValue("password");
return `Basic ${btoa(`${username}:${password}`)}`;
const key = super.getSecretValue("opnsenseApiKey");
const secret = super.getSecretValue("opnsenseApiSecret");
return `Basic ${btoa(`${key}:${secret}`)}`;
}
public async getFirewallVersionAsync(): Promise<FirewallVersionSummary> {
@@ -64,7 +62,7 @@ export class OPNsenseIntegration extends Integration implements FirewallSummaryI
}
private getInterfacesChannel() {
return createChannelEventHistory<FirewallInterface[]>(`integration:${this.integration.id}:interfaces`, 15);
return createChannelEventHistoryOld<FirewallInterface[]>(`integration:${this.integration.id}:interfaces`, 15);
}
public async getFirewallInterfacesAsync(): Promise<FirewallInterfacesSummary[]> {

View File

@@ -33,10 +33,10 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.2.2",
"@mantine/core": "^8.2.4",
"@tabler/icons-react": "^3.34.1",
"dayjs": "^1.11.13",
"next": "15.4.5",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1",
"zod": "^3.25.76"

View File

@@ -24,8 +24,8 @@
"dependencies": {
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.2.2",
"@mantine/hooks": "^8.2.2",
"@mantine/core": "^8.2.4",
"@mantine/hooks": "^8.2.4",
"react": "19.1.1"
},
"devDependencies": {

View File

@@ -24,7 +24,7 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/ui": "workspace:^0.1.0",
"@mantine/notifications": "^8.2.2",
"@mantine/notifications": "^8.2.4",
"@tabler/icons-react": "^3.34.1"
},
"devDependencies": {

View File

@@ -37,10 +37,10 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.2.2",
"@mantine/hooks": "^8.2.2",
"@mantine/core": "^8.2.4",
"@mantine/hooks": "^8.2.4",
"adm-zip": "0.5.16",
"next": "15.4.5",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1",
"superjson": "2.2.2",

View File

@@ -15,6 +15,8 @@ export {
createGetSetChannel,
} from "./lib/channel";
export { createIntegrationHistoryChannel } from "./lib/channels/history-channel";
export const exampleChannel = createSubPubChannel<{ message: string }>("example");
export const pingChannel = createSubPubChannel<
{ url: string; statusCode: number; durationMs: number } | { url: string; error: string }

View File

@@ -226,7 +226,48 @@ export const createItemChannel = <TData>(itemId: string) => {
return createChannelWithLatestAndEvents<TData>(`item:${itemId}`);
};
export const createChannelEventHistory = <TData>(channelName: string, maxElements = 15) => {
export const createChannelEventHistory = <TData>(channelName: string, maxElements = 32) => {
return {
subscribe: (callback: (data: TData) => void) => {
return ChannelSubscriptionTracker.subscribe(channelName, (message) => {
callback(superjson.parse(message));
});
},
pushAsync: async (data: TData, options = { publish: false }) => {
if (options.publish) await publisher.publish(channelName, superjson.stringify(data));
await getSetClient.lpush(channelName, superjson.stringify({ data, timestamp: new Date() }));
await getSetClient.ltrim(channelName, 0, maxElements);
},
clearAsync: async () => {
await getSetClient.del(channelName);
},
/**
* Returns a slice of the available data in the channel.
* If any of the indexes are out of range (or -range), returned data will be clamped.
* @param startIndex Start index of the slice, negative values are counted from the end, defaults at beginning of range.
* @param endIndex End index of the slice, negative values are counted from the end, defaults at end of range.
*/
getSliceAsync: async (startIndex = 0, endIndex = -1) => {
const range = await getSetClient.lrange(channelName, startIndex, endIndex);
return range.map((item) => superjson.parse<{ data: TData; timestamp: Date }>(item));
},
getSliceUntilTimeAsync: async (time: Date) => {
const itemsInCollection = await getSetClient.lrange(channelName, 0, -1);
return itemsInCollection
.map((item) => superjson.parse<{ data: TData; timestamp: Date }>(item))
.filter((item) => item.timestamp < time);
},
getLengthAsync: async () => {
return await getSetClient.llen(channelName);
},
name: channelName,
};
};
/**
* @deprecated This function should no longer be used, see history-channel functions.
*/
export const createChannelEventHistoryOld = <TData>(channelName: string, maxElements = 15) => {
const popElementsOverMaxAsync = async () => {
const length = await getSetClient.llen(channelName);
if (length <= maxElements) {

View File

@@ -0,0 +1,6 @@
import { createChannelEventHistory } from "../channel";
export const createIntegrationHistoryChannel = <TData>(integrationId: string, queryKey: string, maxElements = 32) => {
const channelName = `integration:${integrationId}:history:${queryKey}`;
return createChannelEventHistory<TData>(channelName, maxElements);
};

View File

@@ -26,8 +26,8 @@
"@homarr/api": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/dates": "^8.2.2",
"next": "15.4.5",
"@mantine/dates": "^8.2.4",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1"
},

View File

@@ -33,12 +33,12 @@
"@homarr/settings": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.2.2",
"@mantine/hooks": "^8.2.2",
"@mantine/spotlight": "^8.2.2",
"@mantine/core": "^8.2.4",
"@mantine/hooks": "^8.2.4",
"@mantine/spotlight": "^8.2.4",
"@tabler/icons-react": "^3.34.1",
"jotai": "^2.12.5",
"next": "15.4.5",
"jotai": "^2.13.0",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1",
"use-deep-compare-effect": "^1.8.1"

View File

@@ -32,7 +32,7 @@
"dayjs": "^1.11.13",
"deepmerge": "4.3.1",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.4.5",
"next": "15.4.6",
"next-intl": "4.3.4",
"react": "19.1.1",
"react-dom": "19.1.1"

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "展开详情"
},
"showOnlyIcon": {
"label": "仅显示图标"
},
"topReleases": {
"label": "热门发布",
"description": "要显示的最新版本的最大数量。零表示没有限制。"
@@ -2273,7 +2276,9 @@
"listFoundImages": "找到的映像列表",
"listAlreadyImportedImages": "已导入的映像列表",
"allImagesAlreadyImported": "所有映像已导入",
"onlyAdminCanImport": "只有管理员才能从 docker 导入"
"onlyAdminCanImport": "只有管理员才能从 docker 导入",
"selectAll": "全选",
"deselectAll": "反选"
},
"provider": {
"label": "提供者"
@@ -2335,6 +2340,7 @@
"starsCount": "星",
"forksCount": "复刻",
"issuesCount": "打开问题",
"markViewed": "标记已读",
"openProjectPage": "打开项目页面",
"openReleasePage": "打开发布页面",
"releaseDescription": "发布说明",
@@ -2407,11 +2413,52 @@
"internalServerError": "获取网络控制器概述失败"
}
},
"firewall": {
"name": "防火墙监测",
"description": "显示防火墙摘要",
"tab": {
"system": "系统",
"interfaces": "接口"
},
"error": {
"internalServerError": "无法从防火墙获取数据"
},
"option": {
"interfaces": "要显示的网络接口"
},
"widget": {
"fwname": "名称",
"version": "版本",
"versiontitle": "版本",
"cputitle": "CPU 利用率",
"memorytitle": "内存占用率",
"cpu": "CPU",
"memory": "内存",
"interfaces": {
"name": "名称",
"trans": "已传输",
"recv": "已接收",
"title": "网络接口"
}
}
},
"notifications": {
"name": "通知",
"description": "在集成中显示通知历史",
"noItems": "没有可显示的通知。",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": "Docker 容器"
},
"firewallCpu": {
"label": "防火墙 CPU"
},
"firewallMemory": {
"label": "防火墙内存"
},
"firewallVersion": {
"label": "防火墙版本"
},
"firewallInterfaces": {
"label": "防火墙接口"
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "Vis detaljer"
},
"showOnlyIcon": {
"label": "Vis kun ikon"
},
"topReleases": {
"label": "Top Udgivelser",
"description": "Det maksimale antal seneste udgivelser at vise. Nul betyder ingen grænse."
@@ -2273,7 +2276,9 @@
"listFoundImages": "Liste over fundne billeder",
"listAlreadyImportedImages": "Liste over allerede importerede billeder",
"allImagesAlreadyImported": "Alle billeder allerede importeret",
"onlyAdminCanImport": "Kun administratorer kan importere fra docker"
"onlyAdminCanImport": "Kun administratorer kan importere fra docker",
"selectAll": "Vælg alle",
"deselectAll": "Fravælg alle"
},
"provider": {
"label": "Udbyder"
@@ -2335,6 +2340,7 @@
"starsCount": "Stjerner",
"forksCount": "Forks",
"issuesCount": "Åbne Problemer",
"markViewed": "Marker som vist",
"openProjectPage": "Åbn Projektside",
"openReleasePage": "Åbn Udgivelsesside",
"releaseDescription": "Udgivelse Beskrivelse",
@@ -2407,11 +2413,52 @@
"internalServerError": "Kunne ikke hente Netværkskontroloversigt"
}
},
"firewall": {
"name": "Firewall overvågning",
"description": "Viser en oversigt over firewalls",
"tab": {
"system": "System",
"interfaces": "Grænseflader"
},
"error": {
"internalServerError": "Kan ikke hente data fra firewall"
},
"option": {
"interfaces": "Netværksgrænseflader der vises"
},
"widget": {
"fwname": "Navn",
"version": "Version",
"versiontitle": "Versioner",
"cputitle": "CPU-forbrug",
"memorytitle": "Hukommelsesforbrug",
"cpu": "CPU",
"memory": "Hukommelse",
"interfaces": {
"name": "navn",
"trans": "Overført",
"recv": "Modtaget",
"title": "Netværksgrænseflader"
}
}
},
"notifications": {
"name": "Notifikationer",
"description": "Vis notifikationshistorik fra en integration",
"noItems": "Ingen notifikationer at vise.",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": "Docker containers"
},
"firewallCpu": {
"label": "Firewall CPU"
},
"firewallMemory": {
"label": "Firewall Hukommelse"
},
"firewallVersion": {
"label": "Firewall Version"
},
"firewallInterfaces": {
"label": "Firewall Grænseflader"
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -23,7 +23,7 @@
}
},
"importSettings": {
"title": "Importeinstellungen",
"title": "Einstellungen Importieren",
"description": "Importverhalten konfigurieren"
},
"boardSelection": {
@@ -302,7 +302,7 @@
"group": {
"title": "Benutzergruppen",
"name": "Benutzergruppe",
"search": "Finde eine Benutzergruppe",
"search": "Gruppe suchen",
"field": {
"name": "Name",
"members": "Mitglieder",
@@ -355,15 +355,15 @@
},
"view-all": {
"label": "Alle Boards anzeigen",
"description": "Mitgliedern das Ansehen von Boards erlauben"
"description": "Mitgliedern das Ansehen von allen Boards erlauben"
},
"modify-all": {
"label": "Alle Boards ändern",
"description": "Erlaube Mitgliedern alle Boards zu ändern (beinhaltet keine Zugangskontrolle und Gefahrenbereich)"
"description": "Mitgliedern erlauben, alle Boards zu ändern (beinhaltet keine Zugangskontrolle und Gefahrenbereich)"
},
"full-all": {
"label": "Voller Board Zugriff",
"description": "Erlaube Mitgliedern alle Boards (einschließlich Zugriffskontrolle und Gefahrenbereich) anzuzeigen, zu ändern und zu löschen"
"description": "Mitgliedern erlauben, alle Boards (einschließlich Zugriffskontrolle und Gefahrenbereich) anzuzeigen, zu ändern und zu löschen"
}
}
},
@@ -376,7 +376,7 @@
},
"use-all": {
"label": "Alle Integrationen nutzen",
"description": "Erlaubt Mitgliedern Integrationen zu ihren Boards hinzuzufügen"
"description": "Mitgliedern erlauben, alle Integrationen zu ihren Boards hinzuzufügen"
},
"interact-all": {
"label": "Mit jeder Integration interagieren",
@@ -384,7 +384,7 @@
},
"full-all": {
"label": "Voller Zugriff auf Integrationen",
"description": "Erlaube Mitgliedern jede Integration zu verwalten, zu nutzen und zu interagieren"
"description": "Mitgliedern erlauben, jede Integration zu verwalten, zu nutzen und mit ihnen zu interagieren"
}
}
},
@@ -397,7 +397,7 @@
},
"view-all": {
"label": "Alle Medien anzeigen",
"description": "Erlaubt Mitgliedern alle Medien anzusehen"
"description": "Mitgliedern erlauben, alle Medien anzuzeigen"
},
"full-all": {
"label": "Vollständiger Medienzugriff",
@@ -410,7 +410,7 @@
"item": {
"view-logs": {
"label": "Logs anzeigen",
"description": "Erlaubt Mitgliedern Logs anzusehen"
"description": "Mitgliedern erlauben, Logs anzuzeigen"
}
}
},
@@ -453,7 +453,7 @@
},
"transfer": {
"label": "Eigentum übertragen",
"description": "Übertrage den Eigentümer dieser Gruppe an einen anderen Benutzer.",
"description": "Den Eigentümer dieser Gruppe an einen anderen Benutzer übertragen.",
"confirm": "Bist du sicher, dass du das Eigentum für die Gruppe {name} an {username} übertragen möchtest?",
"notification": {
"success": {
@@ -687,8 +687,8 @@
"description": "Integration \"{kind}\" kann mit den Suchmaschinen verwendet werden. Wählen Sie dies, um die Suchmaschine automatisch zu konfigurieren."
},
"createApp": {
"label": "Anwendung erstellen",
"description": "Erstelle eine App mit dem gleichen Namen und Symbol wie die Integration. Lassen Sie das Eingabefeld unter leer, um die App mit der Integrations URL zu erstellen."
"label": "App erstellen",
"description": "Eine App mit dem gleichen Namen und Symbol wie die Integration erstellen. Lassen Sie das Eingabefeld unter leer, um die App mit der Integrations URL zu erstellen."
},
"appHref": {
"placeholder": "Benutzerdefinierte App URL"
@@ -705,12 +705,12 @@
"error": {
"common": {
"cause": {
"title": "Fall mit mehr Details"
"title": "Mehr Details zur Ursache"
}
},
"unknown": {
"title": "Unbekannter Fehler",
"description": "Ein unbekannter Fehler ist aufgetreten, den Fall unten für mehr Details öffnen"
"description": "Ein unbekannter Fehler ist aufgetreten, öffne die Ursache unten, um mehr Details zu sehen"
},
"parse": {
"title": "Fehler beim Parsen",
@@ -721,7 +721,7 @@
"description": "Die Anfrage wurde nicht autorisiert. Bitte überprüfen Sie, ob die Anmeldedaten korrekt sind und Sie diese mit mit den entsprechenden Berechtigungen konfiguriert haben."
},
"statusCode": {
"title": "Antwort Fehler",
"title": "Antwort-Fehler",
"description": "Unerwartete {statusCode} ({reason}) Antwort von <url></url>erhalten. Bitte überprüfen Sie, ob die URL auf die Basis-URL der Integration verweist.",
"otherDescription": "Unerwartete {statusCode} Antwort von <url></url>erhalten. Bitte stellen Sie sicher, dass die URL auf die Basis-URL der Integration zeigt.",
"reason": {
@@ -938,8 +938,8 @@
"newLabel": "Neuer Bereich"
},
"personalAccessToken": {
"label": "",
"newLabel": ""
"label": "Persönlicher Zugangs-Token",
"newLabel": "Neuer Persönliches Zugangs-Token"
},
"topic": {
"label": "Thema",
@@ -2080,32 +2080,32 @@
"globalRatio": "Globales Verhältnis"
},
"mediaReleases": {
"name": "",
"description": "",
"name": "Medien Veröffentlichungen",
"description": "Zeige neu hinzugefügte Medien oder kommende Versionen von verschiedenen Integrationen",
"option": {
"layout": {
"label": "",
"label": "Darstellung",
"option": {
"backdrop": {
"label": ""
"label": "Hintergrund"
},
"poster": {
"label": ""
"label": "Poster"
}
}
},
"showDescriptionTooltip": {
"label": ""
"label": "Beschreibungs des Tooltips anzeigen"
},
"showType": {
"label": ""
"label": "Medientyp Abzeichen anzeigen"
},
"showSource": {
"label": ""
"label": "Integration der Quelle anzeigen"
}
},
"length": {
"duration": ""
"duration": "{length}Minuten"
}
},
"mediaRequests-requestList": {
@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "Details anzeigen"
},
"showOnlyIcon": {
"label": "Nur Symbole anzeigen"
},
"topReleases": {
"label": "Top Releases",
"description": "Die maximale Anzahl der neuesten Versionen, die angezeigt werden sollen. Null bedeutet kein Limit."
@@ -2273,7 +2276,9 @@
"listFoundImages": "Liste der gefundenen Images",
"listAlreadyImportedImages": "Liste der bereits importierten Images",
"allImagesAlreadyImported": "Alle Images wurden bereits importiert",
"onlyAdminCanImport": "Nur Administratoren können vom Docker importieren"
"onlyAdminCanImport": "Nur Administratoren können vom Docker importieren",
"selectAll": "Alles auswählen",
"deselectAll": "Alle abwählen"
},
"provider": {
"label": "Anbieter"
@@ -2323,8 +2328,8 @@
},
"invalid": "Ungültige Repository Definition, bitte überprüfen Sie die Werte",
"noProvider": {
"label": "",
"tooltip": ""
"label": "Keine Anbieter",
"tooltip": "Der Anbieter konnte nicht festgestellt werden, bitte manuell nach dem Import der Bilder festlegen"
}
}
},
@@ -2335,19 +2340,20 @@
"starsCount": "Sterne",
"forksCount": "Ableger",
"issuesCount": "Offene Tickets",
"markViewed": "Als gelesen markieren",
"openProjectPage": "Projektseite öffnen",
"openReleasePage": "Release Seite öffnen",
"releaseDescription": "Release Beschreibung",
"projectDescription": "",
"projectDescription": "Projektbeschreibung",
"created": "Erstellt",
"error": {
"label": "Fehler",
"messages": {
"invalidIdentifier": "",
"invalidIdentifier": "Ungültige Kennung",
"noMatchingVersion": "Keine passende Version gefunden",
"noReleasesFound": "",
"noProviderSeleceted": "",
"noProviderResponse": ""
"noReleasesFound": "Keine Veröffentlichungen gefunden",
"noProviderSeleceted": "Kein Anbieter ausgewählt",
"noProviderResponse": "Keine Antwort vom Anbieter"
}
}
},
@@ -2407,11 +2413,52 @@
"internalServerError": "Fehler beim Abrufen der Netzwerk Controller Zusammenfassung"
}
},
"firewall": {
"name": "Überwachung der Firewall",
"description": "Zeigt eine Zusammenfassung der Firewalls an",
"tab": {
"system": "System",
"interfaces": "Schnittstellen"
},
"error": {
"internalServerError": "Daten von der Firewall konnten nicht abgerufen werden"
},
"option": {
"interfaces": "Netzwerkschnittstellen anzeigen"
},
"widget": {
"fwname": "Name",
"version": "Version",
"versiontitle": "Versionen",
"cputitle": "CPU-Nutzung",
"memorytitle": "Speichernutzung",
"cpu": "CPU",
"memory": "Speicher",
"interfaces": {
"name": "Name",
"trans": "Übertragen",
"recv": "Empfangen",
"title": "Netzwerkschnittstellen"
}
}
},
"notifications": {
"name": "Benachrichtigungen",
"description": "Benachrichtigungshistorie von einer Integration anzeigen",
"noItems": "Keine Benachrichtigungen zum Anzeigen.",
"option": {}
},
"systemResources": {
"name": "Systemressourcen",
"description": "CPU, Arbeitsspeicher, Festplatte und andere Hardware-Nutzung Ihres Systems",
"option": {},
"card": {
"cpu": "CPU",
"memory": "Arbeitsspeicher",
"network": "Netzwerk",
"up": "OBEN",
"down": "UNTEN"
}
}
},
"widgetPreview": {
@@ -2599,7 +2646,7 @@
"label": "Symbolfarbe"
},
"clearColor": {
"label": ""
"label": "Farbe entfernen"
},
"customCss": {
"label": "Benutzerdefinierte css für dieses Board",
@@ -3186,21 +3233,33 @@
},
"dockerContainers": {
"label": "Docker Container"
},
"firewallCpu": {
"label": "Firewall CPU"
},
"firewallMemory": {
"label": "Firewall Speicher"
},
"firewallVersion": {
"label": "Firewall Version"
},
"firewallInterfaces": {
"label": "Firewall Schnittstellen"
}
},
"interval": {
"seconds": "Alle(r) {interval, plural, =1 {Sekunde} other {# Sekunden}}",
"minutes": "Alle(r) {interval, plural, one {}=1 {Minute} other {# Minuten}}",
"hours": "Alle(r) {interval, plural, one {}=1 {Stunde} other {# Stunden}}",
"seconds": "Jeweils {interval, plural, =1 {Sekunde} other {# Sekunden}}",
"minutes": "Jeweils {interval, plural, =1 {Minute} other {# Minuten}}",
"hours": "Jeweils {interval, plural, =1 {Stunde} other {# Stunden}}",
"midnight": "Jeden Tag um Mitternacht",
"weeklyMonday": "Jede Woche am Montag"
},
"settings": {
"title": "Aufgabeneinstellungen für {jobName}"
"title": "Einstellungen der Aufgabe für {jobName}"
},
"field": {
"interval": {
"label": "Zeitplanintervall"
"label": "Intervall des Zeitplans"
}
}
},
@@ -3273,7 +3332,7 @@
"label": "Name"
},
"state": {
"label": "Staat",
"label": "Status",
"option": {
"created": "Erstellt",
"running": "Aktiv",
@@ -3653,7 +3712,7 @@
},
"action": {
"saveUser": "Benutzerberechtigung hinzufügen",
"saveGroup": "Gruppenberechtigung hinzufügen"
"saveGroup": "Gruppenberechtigung speichern"
}
},
"navigationStructure": {
@@ -4237,10 +4296,10 @@
"log": {
"level": {
"option": {
"debug": "",
"info": "",
"warn": "",
"error": ""
"debug": "Debug",
"info": "Info",
"warn": "Hinweis",
"error": "Fehler"
}
}
}

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -944,6 +944,14 @@
"topic": {
"label": "Topic",
"newLabel": "New topic"
},
"opnsenseApiKey": {
"label": "API Key (Key)",
"newLabel": "New API Key (Key)"
},
"opnsenseApiSecret": {
"label": "API Key (Secret)",
"newLabel": "New API Key (Secret)"
}
}
},
@@ -2447,6 +2455,18 @@
"description": "Display notification history from an integration",
"noItems": "No notifications to display.",
"option": {}
},
"systemResources": {
"name": "System resources",
"description": "CPU, Memory, Disk and other hardware usage of your system",
"option": {},
"card": {
"cpu": "CPU",
"memory": "MEM",
"network": "NET",
"up": "UP",
"down": "DOWN"
}
}
},
"widgetPreview": {

View File

@@ -7,15 +7,15 @@
"description": "Para empezar, por favor, seleccione cómo desea configurar su instancia de Homarr.",
"action": {
"scratch": "Empezar de cero",
"importOldmarr": "Importar de Homarr antes de 1.0"
"importOldmarr": "Importar desde Homarr antes de la versión 1.0"
}
},
"import": {
"title": "Importar datos",
"subtitle": "Puede importar datos de una instancia de Homarr existente.",
"subtitle": "Puedes importar datos de una instancia de Homarr existente.",
"dropzone": {
"title": "Arrastre el archivo zip aquí o haga clic para navegar",
"description": "El zip subido será procesado y podrás seleccionar lo que quieres importar"
"title": "Arrastre el archivo ZIP aquí o haga clic para navegar",
"description": "El archivo ZIP subido será procesado y podrás seleccionar lo que quieres importar"
},
"fileInfo": {
"action": {
@@ -24,11 +24,11 @@
},
"importSettings": {
"title": "Importar ajustes",
"description": ""
"description": "Configurar el comportamiento de la importación"
},
"boardSelection": {
"title": "Se encontraron {count} tableros",
"description": "",
"description": "Elige todos los tableros con el tamaño que deseas para importar",
"action": {
"selectAll": "Seleccionar todo",
"unselectAll": "Deseleccionar todo"
@@ -36,7 +36,7 @@
},
"summary": {
"title": "Resumen de importación",
"description": "",
"description": "En el resumen de abajo puedes ver qué se importará",
"action": {
"import": "Confirmar la importación y continuar"
},
@@ -57,15 +57,15 @@
},
"notification": {
"error": {
"title": "Token invalido",
"message": ""
"title": "Token inválido",
"message": "El código que has introducido no es válido"
}
}
}
},
"user": {
"title": "Usuario administrador",
"subtitle": "",
"subtitle": "Especifica las credenciales para tu usuario administrador.",
"notification": {
"success": {
"title": "Usuario creado",
@@ -91,14 +91,14 @@
"subtitle": "Configurar ajustes del servidor."
},
"finish": {
"title": "",
"title": "Finalizar la configuración",
"subtitle": "",
"description": "",
"description": "Ha completado el proceso de configuración con éxito. Puede empezar a utilizar Homarr. Seleccione su siguiente paso:",
"action": {
"goToBoard": "Ir al tablero {name}",
"createBoard": "",
"inviteUser": "",
"docs": ""
"createBoard": "Crea tu primer tablero",
"inviteUser": "Invite a otros usuarios",
"docs": "Consulte la documentación"
}
}
},
@@ -110,12 +110,12 @@
"page": {
"login": {
"title": "Inicia sesión en tu cuenta",
"subtitle": ""
"subtitle": "¡Bienvenido de nuevo! Por favor introduzca sus credenciales"
},
"invite": {
"title": "",
"subtitle": "",
"description": ""
"title": "Unase a Homarr",
"subtitle": "¡Bienvenido a Homarr! Por favor cree su cuenta",
"description": "Usted fue invitado por {username}"
},
"init": {
"title": "Nueva instalación de Homarr",
@@ -137,7 +137,7 @@
"lowercase": "Incluye letra minúscula",
"uppercase": "Incluye letra mayúscula",
"number": "Incluye número",
"special": ""
"special": "Incluye símbolos especiales"
}
},
"passwordConfirm": {
@@ -147,20 +147,20 @@
"label": "Contraseña anterior"
},
"homeBoard": {
"label": ""
"label": "Tablero principal"
},
"pingIconsEnabled": {
"label": "Usar iconos para pings"
},
"defaultSearchEngine": {
"label": ""
"label": "Motor de búsqueda predeterminado"
},
"openSearchInNewTab": {
"label": ""
"label": "Abrir los resultados de búsqueda en una nueva pestaña"
}
},
"error": {
"usernameTaken": ""
"usernameTaken": "Nombre de usuario en uso"
},
"action": {
"login": {
@@ -302,7 +302,7 @@
"group": {
"title": "",
"name": "",
"search": "",
"search": "Encontrar un grupo",
"field": {
"name": "Nombre",
"members": "Miembros",
@@ -355,11 +355,11 @@
},
"view-all": {
"label": "",
"description": ""
"description": "Permitir a los miembros ver todos los tableros"
},
"modify-all": {
"label": "",
"description": ""
"description": "Permitir a los miembros modificar todos tableros (Esto no incluye los controles de acceso y la zona de peligro)"
},
"full-all": {
"label": "",
@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "Afficher les détails"
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "Meilleures sorties",
"description": "Le nombre maximum de dernières versions à afficher. Zéro signifie aucune limite."
@@ -2273,7 +2276,9 @@
"listFoundImages": "Liste des images trouvées",
"listAlreadyImportedImages": "Liste des images déjà importées",
"allImagesAlreadyImported": "Toutes les images déjà importées",
"onlyAdminCanImport": "Seuls les administrateurs peuvent importer depuis docker"
"onlyAdminCanImport": "Seuls les administrateurs peuvent importer depuis docker",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": "Fournisseur"
@@ -2335,6 +2340,7 @@
"starsCount": "Étoiles",
"forksCount": "",
"issuesCount": "Problèmes ouverts",
"markViewed": "",
"openProjectPage": "Ouvrir la page du projet",
"openReleasePage": "Ouvrir la page de publication",
"releaseDescription": "Description de la publication",
@@ -2407,11 +2413,52 @@
"internalServerError": "Impossible de récupérer le résumé du contrôleur réseau"
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "Notifications",
"description": "Afficher l'historique des notifications à partir d'une intégration",
"noItems": "Aucune notification à afficher.",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": "Conteneurs Docker"
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "הצג פרטים"
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "מהדורות מובילות",
"description": "המספר המרבי של מהדורות אחרונות להצגה. אפס פירושו שאין הגבלה."
@@ -2273,7 +2276,9 @@
"listFoundImages": "רשימת התמונות שנמצאו",
"listAlreadyImportedImages": "רשימת התמונות שכבר יובאו",
"allImagesAlreadyImported": "כל התמונות כבר יובאו",
"onlyAdminCanImport": "רק מנהלים יכולים לייבא מדוקר"
"onlyAdminCanImport": "רק מנהלים יכולים לייבא מדוקר",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": "ספק"
@@ -2335,6 +2340,7 @@
"starsCount": "כוכבים",
"forksCount": "פיצולים",
"issuesCount": "תקלות פתוחות",
"markViewed": "",
"openProjectPage": "פתח את דף הפרויקט",
"openReleasePage": "פתח את דף הגרסאות",
"releaseDescription": "תיאור הגרסה",
@@ -2407,11 +2413,52 @@
"internalServerError": "אחזור תקציר בקר הרשת נכשל"
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "התראות",
"description": "הצגת היסטוריית התראות מאינטגרציה",
"noItems": "אין התראות להצגה.",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": "מכולות דוקר"
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "詳細を表示"
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "トップリリース",
"description": "表示する最新リリースの最大数。ゼロは制限なしです。"
@@ -2273,7 +2276,9 @@
"listFoundImages": "見つかったイメージの一覧",
"listAlreadyImportedImages": "すでにインポートされたイメージのリスト",
"allImagesAlreadyImported": "すでにインポートされた全てのイメージ",
"onlyAdminCanImport": "管理者のみが Docker からインポートできます"
"onlyAdminCanImport": "管理者のみが Docker からインポートできます",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": "プロバイダー"
@@ -2335,6 +2340,7 @@
"starsCount": "スター数",
"forksCount": "フォーク数",
"issuesCount": "未解決の課題数",
"markViewed": "",
"openProjectPage": "プロジェクトページを開く",
"openReleasePage": "リリースページを開く",
"releaseDescription": "リリースの説明",
@@ -2407,11 +2413,52 @@
"internalServerError": "ネットワークコントローラの概要の取得に失敗しました"
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "通知",
"description": "連携機能からの通知履歴を表示する",
"noItems": "表示する通知はありません。",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": "Docker コンテナ"
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": "Netwerkcontroller samenvatting ophalen mislukt"
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "Zobraziť podrobnosti"
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "Najlepšie vydania",
"description": "Maximálny počet najnovších vydaní na zobrazenie. Nula znamená žiadny limit."
@@ -2273,7 +2276,9 @@
"listFoundImages": "Zoznam nájdených obrázkov",
"listAlreadyImportedImages": "Zoznam už importovaných obrázkov",
"allImagesAlreadyImported": "Všetky obrázky sú už importované",
"onlyAdminCanImport": "Importovať z dockeru môžu iba správcovia"
"onlyAdminCanImport": "Importovať z dockeru môžu iba správcovia",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": "Poskytovateľ"
@@ -2335,6 +2340,7 @@
"starsCount": "Hviezdy",
"forksCount": "Vidlicový",
"issuesCount": "Problémy",
"markViewed": "",
"openProjectPage": "Otvorte stránku projektu",
"openReleasePage": "Otvorte stránku vydania",
"releaseDescription": "Popis vydania",
@@ -2407,11 +2413,52 @@
"internalServerError": "Nepodarilo sa načítať súhrn sieťového ovládača"
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": "Docker kontajnery"
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "Ayrıntıları Göster"
},
"showOnlyIcon": {
"label": "Yalnızca İkon Göster"
},
"topReleases": {
"label": "En İyi Sürümler",
"description": "Gösterilecek en son sürümlerin maksimum sayısı. Sıfır, sınır olmadığı anlamına gelir."
@@ -2273,7 +2276,9 @@
"listFoundImages": "Bulunan imajların listesi",
"listAlreadyImportedImages": "Daha önce içe aktarılan imajların listesi",
"allImagesAlreadyImported": "Tüm imajlar daha önce içe aktarıldı",
"onlyAdminCanImport": "Sadece yöneticiler docker'dan içe aktarabilir"
"onlyAdminCanImport": "Sadece yöneticiler docker'dan içe aktarabilir",
"selectAll": "Tümünü seç",
"deselectAll": "Tüm seçimleri kaldır"
},
"provider": {
"label": "Sağlayıcı"
@@ -2335,6 +2340,7 @@
"starsCount": "Yıldızlar",
"forksCount": "Çatallar",
"issuesCount": "Sorunları Aç",
"markViewed": "Görüntülenmiş olarak işaretle",
"openProjectPage": "Proje Sayfasını Aç",
"openReleasePage": "Sürüm Sayfasını Aç",
"releaseDescription": "Sürüm Açıklaması",
@@ -2407,11 +2413,52 @@
"internalServerError": "Ağ Denetleyicisi Özeti alınamadı"
}
},
"firewall": {
"name": "Güvenlik Duvarı İzleme",
"description": "Güvenlik duvarlarının özetini gösterir",
"tab": {
"system": "Sistem",
"interfaces": "Arayüzler"
},
"error": {
"internalServerError": "Güvenlik duvarından veri alınamıyor"
},
"option": {
"interfaces": "Gösterilecek ağ arayüzleri"
},
"widget": {
"fwname": "İsim",
"version": "Sürüm",
"versiontitle": "Sürümler",
"cputitle": "CPU kullanımı",
"memorytitle": "Bellek kullanımı",
"cpu": "İşlemci",
"memory": "Bellek",
"interfaces": {
"name": "i̇sim",
"trans": "Gönderilen",
"recv": "Alınan",
"title": "Ağ Arayüzleri"
}
}
},
"notifications": {
"name": "Bildirimler",
"description": "Entegrasyonların bildirim geçmişini görüntüle",
"noItems": "Görüntülenecek bildirim yok.",
"option": {}
},
"systemResources": {
"name": "Sistem kaynakları",
"description": "Sisteminizin CPU, Bellek, Disk ve diğer donanım kullanımları",
"option": {},
"card": {
"cpu": "İşlemci",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": "Docker konteynerleri"
},
"firewallCpu": {
"label": "Güvenlik Duvarı İşlemcisi"
},
"firewallMemory": {
"label": "Güvenlik Duvarı Belleği"
},
"firewallVersion": {
"label": "Güvenlik Duvarı Sürümü"
},
"firewallInterfaces": {
"label": "Güvenlik Duvarı Arayüzleri"
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": ""
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": ""
@@ -2335,6 +2340,7 @@
"starsCount": "",
"forksCount": "",
"issuesCount": "",
"markViewed": "",
"openProjectPage": "",
"openReleasePage": "",
"releaseDescription": "",
@@ -2407,11 +2413,52 @@
"internalServerError": ""
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -2257,6 +2257,9 @@
"showDetails": {
"label": "顯示詳情"
},
"showOnlyIcon": {
"label": ""
},
"topReleases": {
"label": "",
"description": ""
@@ -2273,7 +2276,9 @@
"listFoundImages": "",
"listAlreadyImportedImages": "",
"allImagesAlreadyImported": "",
"onlyAdminCanImport": ""
"onlyAdminCanImport": "",
"selectAll": "",
"deselectAll": ""
},
"provider": {
"label": "提供者"
@@ -2335,6 +2340,7 @@
"starsCount": "星標",
"forksCount": "分支數",
"issuesCount": "開放問題",
"markViewed": "",
"openProjectPage": "開啟專案頁面",
"openReleasePage": "開啟發布葉面",
"releaseDescription": "版本描述",
@@ -2407,11 +2413,52 @@
"internalServerError": "無法獲取網路控制總覽"
}
},
"firewall": {
"name": "",
"description": "",
"tab": {
"system": "",
"interfaces": ""
},
"error": {
"internalServerError": ""
},
"option": {
"interfaces": ""
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
}
}
},
"notifications": {
"name": "",
"description": "",
"noItems": "",
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
}
}
},
"widgetPreview": {
@@ -3186,6 +3233,18 @@
},
"dockerContainers": {
"label": ""
},
"firewallCpu": {
"label": ""
},
"firewallMemory": {
"label": ""
},
"firewallVersion": {
"label": ""
},
"firewallInterfaces": {
"label": ""
}
},
"interval": {

View File

@@ -30,12 +30,12 @@
"@homarr/log": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.2.2",
"@mantine/dates": "^8.2.2",
"@mantine/hooks": "^8.2.2",
"@mantine/core": "^8.2.4",
"@mantine/dates": "^8.2.4",
"@mantine/hooks": "^8.2.4",
"@tabler/icons-react": "^3.34.1",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.4.5",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1",
"svgson": "^5.3.1"

View File

@@ -1,3 +1,4 @@
@import "@mantine/core/styles.css";
@import "@mantine/charts/styles.css";
@import "@mantine/dates/styles.css";
@import "mantine-react-table/styles.css";

View File

@@ -48,9 +48,9 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/charts": "^8.2.2",
"@mantine/core": "^8.2.2",
"@mantine/hooks": "^8.2.2",
"@mantine/charts": "^8.2.4",
"@mantine/core": "^8.2.4",
"@mantine/hooks": "^8.2.4",
"@tabler/icons-react": "^3.34.1",
"@tiptap/extension-color": "2.26.1",
"@tiptap/extension-highlight": "2.26.1",
@@ -71,12 +71,12 @@
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.4.5",
"next": "15.4.6",
"react": "19.1.1",
"react-dom": "19.1.1",
"react-markdown": "^10.1.0",
"recharts": "^2.15.4",
"video.js": "^8.23.3",
"video.js": "^8.23.4",
"zod": "^3.25.76"
},
"devDependencies": {

View File

@@ -3,7 +3,7 @@ import { IconBrain } from "@tabler/icons-react";
import { progressColor } from "../system-health";
export const MemoryRing = ({ available, used, isTiny }: { available: string; used: string; isTiny: boolean }) => {
export const MemoryRing = ({ available, used, isTiny }: { available: number; used: number; isTiny: boolean }) => {
const memoryUsage = formatMemoryUsage(available, used);
return (
@@ -31,14 +31,12 @@ export const MemoryRing = ({ available, used, isTiny }: { available: string; use
);
};
export const formatMemoryUsage = (memFree: string, memUsed: string) => {
const memFreeBytes = Number(memFree);
const memUsedBytes = Number(memUsed);
const totalMemory = memFreeBytes + memUsedBytes;
const memFreeGB = (memFreeBytes / 1024 ** 3).toFixed(2);
const memUsedGB = (memUsedBytes / 1024 ** 3).toFixed(2);
const memFreePercent = Math.round((memFreeBytes / totalMemory) * 100);
const memUsedPercent = Math.round((memUsedBytes / totalMemory) * 100);
export const formatMemoryUsage = (memFree: number, memUsed: number) => {
const totalMemory = memFree + memUsed;
const memFreeGB = (memFree / 1024 ** 3).toFixed(2);
const memUsedGB = (memUsed / 1024 ** 3).toFixed(2);
const memFreePercent = Math.round((memFree / totalMemory) * 100);
const memUsedPercent = Math.round((memUsed / totalMemory) * 100);
const memTotalGB = (totalMemory / 1024 ** 3).toFixed(2);
return {

View File

@@ -89,7 +89,7 @@ export const SystemHealthMonitoring = ({
<Stack h="100%" gap="sm" className="health-monitoring">
{healthData.map(({ integrationId, integrationName, healthInfo, updatedAt }) => {
const disksData = matchFileSystemAndSmart(healthInfo.fileSystem, healthInfo.smart);
const memoryUsage = formatMemoryUsage(healthInfo.memAvailable, healthInfo.memUsed);
const memoryUsage = formatMemoryUsage(healthInfo.memAvailableInBytes, healthInfo.memUsedInBytes);
return (
<Stack
gap="sm"
@@ -176,7 +176,11 @@ export const SystemHealthMonitoring = ({
<CpuTempRing fahrenheit={options.fahrenheit} cpuTemp={healthInfo.cpuTemp} isTiny={isTiny} />
)}
{options.memory && (
<MemoryRing available={healthInfo.memAvailable} used={healthInfo.memUsed} isTiny={isTiny} />
<MemoryRing
available={healthInfo.memAvailableInBytes}
used={healthInfo.memUsedInBytes}
isTiny={isTiny}
/>
)}
</Flex>
{

View File

@@ -37,6 +37,7 @@ import * as rssFeed from "./rssFeed";
import * as smartHomeEntityState from "./smart-home/entity-state";
import * as smartHomeExecuteAutomation from "./smart-home/execute-automation";
import * as stockPrice from "./stocks";
import * as systemResources from "./system-resources";
import * as video from "./video";
import * as weather from "./weather";
@@ -73,6 +74,7 @@ export const widgetImports = {
firewall,
notifications,
mediaReleases,
systemResources,
} satisfies WidgetImportRecord;
export type WidgetImports = typeof widgetImports;

View File

@@ -0,0 +1,56 @@
import { Box, Group, Paper, Stack, Text } from "@mantine/core";
import { humanFileSize } from "@homarr/common";
import { useScopedI18n } from "@homarr/translation/client";
import { CommonChart } from "./common-chart";
export const CombinedNetworkTrafficChart = ({
usageOverTime,
}: {
usageOverTime: {
up: number;
down: number;
}[];
}) => {
const chartData = usageOverTime.map((usage, index) => ({ index, up: usage.up, down: usage.down }));
const t = useScopedI18n("widget.systemResources.card");
return (
<CommonChart
data={chartData}
dataKey={"index"}
series={[
{ name: "up", color: "orange.5" },
{ name: "down", color: "yellow.5" },
]}
title={t("network")}
yAxisProps={{ domain: [0, "dataMax"] }}
tooltipProps={{
content: ({ payload }) => {
if (!payload) {
return null;
}
return (
<Paper px={3} py={2} withBorder shadow="md" radius="md">
<Stack gap={0}>
{payload.map((payloadData) => (
<Group key={payloadData.key} gap={4}>
<Box bg={payloadData.color} w={10} h={10} style={{ borderRadius: 99 }}></Box>
<Text c="dimmed" size="xs">
{payloadData.value === undefined ? (
<>N/A</>
) : (
<>{humanFileSize(Math.round(payloadData.value))}/s</>
)}
</Text>
</Group>
))}
</Stack>
</Paper>
);
},
}}
/>
);
};

View File

@@ -0,0 +1,97 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { LineChartSeries } from "@mantine/charts";
import { LineChart } from "@mantine/charts";
import { Card, Center, Group, Loader, Stack, Text, useMantineColorScheme, useMantineTheme } from "@mantine/core";
import { useElementSize, useHover, useMergedRef } from "@mantine/hooks";
import type { TooltipProps, YAxisProps } from "recharts";
import { useRequiredBoard } from "@homarr/boards/context";
export const CommonChart = ({
data,
dataKey,
series,
title,
tooltipProps,
yAxisProps,
lastValue,
}: {
data: Record<string, any>[];
dataKey: string;
series: LineChartSeries[];
title: string;
tooltipProps?: TooltipProps<number, any>;
yAxisProps?: Omit<YAxisProps, "ref">;
lastValue?: string;
}) => {
const { ref: elementSizeRef, height } = useElementSize();
const theme = useMantineTheme();
const scheme = useMantineColorScheme();
const board = useRequiredBoard();
const { hovered, ref: hoverRef } = useHover();
const ref = useMergedRef(elementSizeRef, hoverRef);
const opacity = board.opacity / 100;
const backgroundColor =
scheme.colorScheme === "dark" ? `rgba(57, 57, 57, ${opacity})` : `rgba(246, 247, 248, ${opacity})`;
return (
<Card
ref={ref}
h={"100%"}
pos={"relative"}
style={{ overflow: "visible" }}
p={0}
bg={data.length <= 1 ? backgroundColor : undefined}
radius={board.itemRadius}
>
{data.length > 1 && height > 40 && !hovered && (
<Group
pos={"absolute"}
top={0}
left={0}
p={8}
pt={6}
gap={5}
wrap={"nowrap"}
style={{ zIndex: 2, pointerEvents: "none" }}
>
<Text c={"dimmed"} size={height > 100 ? "md" : "xs"} fw={"bold"}>
{title}
</Text>
{lastValue && (
<Text c={"dimmed"} size={height > 100 ? "md" : "xs"} lineClamp={1}>
{lastValue}
</Text>
)}
</Group>
)}
{data.length <= 1 ? (
<Center pos="absolute" w="100%" h="100%">
<Stack px={"xs"} align={"center"}>
<Loader type="bars" size={height > 100 ? "md" : "xs"} color={"rgba(94, 94, 94, 1)"} />
</Stack>
</Center>
) : (
<LineChart
data={data}
dataKey={dataKey}
h={"100%"}
series={series}
curveType="monotone"
tickLine="none"
gridAxis="none"
withXAxis={false}
withYAxis={false}
withDots={false}
bg={backgroundColor}
styles={{ root: { padding: 5, borderRadius: theme.radius[board.itemRadius] } }}
tooltipAnimationDuration={200}
tooltipProps={tooltipProps}
withTooltip={height >= 64}
yAxisProps={yAxisProps}
/>
)}
</Card>
);
};

Some files were not shown because too many files have changed in this diff Show More