chore(release): automatic release v1.40.0

This commit is contained in:
homarr-releases[bot]
2025-10-03 19:13:40 +00:00
committed by GitHub
94 changed files with 6606 additions and 3548 deletions

View File

@@ -33,6 +33,7 @@ body:
options:
# The below comment is used to insert a new version with on-release.yml
#NEXT_VERSION#
- 1.39.0
- 1.38.0
- 1.37.0
- 1.36.1

View File

@@ -6,7 +6,7 @@ on:
- cron: "0 0 * * *" # every day at midnight
permissions:
contents: read # required for code checkout
contents: write # required to push changes
jobs:
download-crowdin-translations:

View File

@@ -64,7 +64,7 @@ jobs:
- uses: actions/setup-node@v5
if: env.SKIP_RELEASE == 'false'
with:
node-version: 22.19.0
node-version: 22.20.0
cache: "pnpm"
- run: npm i -g pnpm
if: env.SKIP_RELEASE == 'false'

2
.nvmrc
View File

@@ -1 +1 @@
22.19.0
22.20.0

View File

@@ -1,4 +1,4 @@
FROM node:22.19.0-alpine AS base
FROM node:22.20.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.3.1",
"@mantine/core": "^8.3.1",
"@mantine/dropzone": "^8.3.1",
"@mantine/hooks": "^8.3.1",
"@mantine/modals": "^8.3.1",
"@mantine/tiptap": "^8.3.1",
"@mantine/colors-generator": "^8.3.2",
"@mantine/core": "^8.3.2",
"@mantine/dropzone": "^8.3.2",
"@mantine/hooks": "^8.3.2",
"@mantine/modals": "^8.3.2",
"@mantine/tiptap": "^8.3.2",
"@million/lint": "1.0.14",
"@tabler/icons-react": "^3.35.0",
"@tanstack/react-query": "^5.89.0",
"@tanstack/react-query-devtools": "^5.89.0",
"@tanstack/react-query-next-experimental": "^5.89.0",
"@trpc/client": "^11.5.1",
"@trpc/next": "^11.5.1",
"@trpc/react-query": "^11.5.1",
"@trpc/server": "^11.5.1",
"@tanstack/react-query": "^5.90.2",
"@tanstack/react-query-devtools": "^5.90.2",
"@tanstack/react-query-next-experimental": "^5.90.2",
"@trpc/client": "^11.6.0",
"@trpc/next": "^11.6.0",
"@trpc/react-query": "^11.6.0",
"@trpc/server": "^11.6.0",
"@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "0.10.0",
"@xterm/xterm": "^5.5.0",
@@ -74,16 +74,16 @@
"dotenv": "^17.2.2",
"flag-icons": "^7.5.0",
"glob": "^11.0.3",
"jotai": "^2.14.0",
"jotai": "^2.15.0",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.5.3",
"next": "15.5.4",
"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.93.0",
"sass": "^1.93.2",
"superjson": "2.2.2",
"swagger-ui-react": "^5.29.0",
"use-deep-compare-effect": "^1.8.1",
@@ -94,9 +94,9 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/chroma-js": "3.1.1",
"@types/node": "^22.18.6",
"@types/node": "^22.18.7",
"@types/prismjs": "^1.26.5",
"@types/react": "19.1.13",
"@types/react": "19.1.15",
"@types/react-dom": "19.1.9",
"@types/swagger-ui-react": "^5.18.0",
"concurrently": "^9.2.1",

View File

@@ -23,6 +23,7 @@ import { useRequiredBoard } from "@homarr/boards/context";
import { useEditMode } from "@homarr/boards/edit-mode";
import { revalidatePathActionAsync } from "@homarr/common/client";
import { env } from "@homarr/common/env";
import { hotkeys } from "@homarr/definitions";
import { useConfirmModal, useModalAction } from "@homarr/modals";
import { AppSelectModal } from "@homarr/modals-collection";
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
@@ -165,7 +166,7 @@ const EditModeMenu = () => {
open();
}, [board, isEditMode, saveBoard, open]);
useHotkeys([["mod+e", toggle]]);
useHotkeys([[hotkeys.toggleBoardEdit, toggle]]);
usePreventLeaveWithDirty(isEditMode);
return (

View File

@@ -120,11 +120,14 @@ export const BackgroundSettingsContent = ({ board }: Props) => {
/>
{session?.user.permissions.includes("media-upload") && (
<UploadMedia
onSuccess={({ url }) =>
onSuccess={(medias) => {
const first = medias.at(0);
if (!first) return;
startTransition(() => {
form.setFieldValue("backgroundImageUrl", url);
})
}
form.setFieldValue("backgroundImageUrl", first.url);
});
}}
>
{({ onClick, loading }) => (
<ActionIcon onClick={onClick} loading={loading} mt={24} size={36} variant="default">

View File

@@ -23,6 +23,7 @@ import type { SupportedLanguage } from "@homarr/translation";
import { isLocaleRTL, isLocaleSupported } from "@homarr/translation";
import { Analytics } from "~/components/layout/analytics";
import { CrowdinLiveTranslation } from "~/components/layout/crowdin-live-translation";
import { SearchEngineOptimization } from "~/components/layout/search-engine-optimization";
import { getCurrentColorSchemeAsync } from "~/theme/color-scheme";
import { DayJsLoader } from "./_client-providers/dayjs-loader";
@@ -118,10 +119,12 @@ export default async function Layout(props: {
(innerProps) => <SpotlightProvider {...innerProps} />,
]);
const { locale } = await props.params;
return (
// Instead of ColorSchemScript we use data-mantine-color-scheme to prevent flickering
<html
lang={(await props.params).locale}
lang={locale}
dir={direction}
data-mantine-color-scheme={colorScheme}
style={{
@@ -132,6 +135,7 @@ export default async function Layout(props: {
<head>
<Analytics />
<SearchEngineOptimization />
<CrowdinLiveTranslation locale={locale} />
</head>
<body className={["font-sans", fontSans.variable].join(" ")}>
<StackedProvider>

View File

@@ -11,14 +11,23 @@ import {
Center,
Flex,
Group,
Kbd,
List,
ListItem,
Stack,
Table,
TableTbody,
TableTd,
TableTh,
TableThead,
TableTr,
Text,
Title,
} from "@mantine/core";
import { IconLanguage, IconLibrary, IconUsers } from "@tabler/icons-react";
import { IconKeyboard, IconLanguage, IconLibrary, IconUsers } from "@tabler/icons-react";
import { capitalize, objectEntries } from "@homarr/common";
import { hotkeys } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server";
import { homarrLogoPath } from "~/components/layout/logo/homarr-logo";
@@ -149,6 +158,45 @@ export default async function AboutPage() {
</List>
</AccordionPanel>
</AccordionItem>
<AccordionItem value="hotkeys">
<AccordionControl icon={<IconKeyboard size="1rem" />}>
<Stack gap={0}>
<Text>{t("accordion.hotkeys.title")}</Text>
<Text size="sm" c="dimmed">
{t("accordion.hotkeys.subtitle")}
</Text>
</Stack>
</AccordionControl>
<AccordionPanel>
<Table>
<TableThead>
<TableTr>
<TableTh>{t("accordion.hotkeys.field.shortcut")}</TableTh>
<TableTh>{t("accordion.hotkeys.field.action")}</TableTh>
</TableTr>
</TableThead>
<TableTbody>
{objectEntries(hotkeys).map(([key, shortcut]) => (
<TableTr key={key}>
<TableTd>
<Kbd size="md">
{shortcut
.split("+")
.map((key) => capitalize(key.trim()))
.join(" + ")}
</Kbd>
</TableTd>
<TableTd>{t(`accordion.hotkeys.action.${key}`)}</TableTd>
</TableTr>
))}
</TableTbody>
</Table>
<Text size="sm" c="dimmed">
{t("accordion.hotkeys.note")}
</Text>
</AccordionPanel>
</AccordionItem>
</Accordion>
</div>
);

View File

@@ -14,7 +14,7 @@ export const UploadMediaButton = () => {
};
return (
<UploadMedia onSettled={onSettledAsync}>
<UploadMedia onSettled={onSettledAsync} multiple>
{({ onClick, loading }) => (
<Button onClick={onClick} loading={loading} rightSection={<IconUpload size={16} stroke={1.5} />}>
{t("media.action.upload.label")}

View File

@@ -1,3 +0,0 @@
.flagIcon {
border-radius: 4px;
}

View File

@@ -6,8 +6,7 @@ import { IconCheck } from "@tabler/icons-react";
import type { SupportedLanguage } from "@homarr/translation";
import { localeConfigurations, supportedLanguages } from "@homarr/translation";
import classes from "./language-combobox.module.css";
import { LanguageIcon } from "@homarr/ui";
import "flag-icons/css/flag-icons.min.css";
@@ -84,7 +83,7 @@ const OptionItem = ({
return (
<Group wrap="nowrap" justify="space-between">
<Group wrap="nowrap">
<span className={`fi fi-${localeConfigurations[localeKey].flagIcon} ${classes.flagIcon}`}></span>
<LanguageIcon icon={localeConfigurations[localeKey].icon} />
<Group wrap="nowrap" gap="xs">
<Text>{localeConfigurations[localeKey].name}</Text>
<Text size="xs" c="dimmed" inherit>

View File

@@ -0,0 +1,17 @@
import Script from "next/script";
import type { SupportedLanguage } from "@homarr/translation";
export const CrowdinLiveTranslation = (props: { locale: SupportedLanguage }) => {
if (props.locale !== "cr") return null;
return (
<>
<Script type="text/javascript" src="//cdn.crowdin.com/jipt/jipt.js"></Script>
<Script type="text/javascript" id="crowdin-configuration">
{`var _jipt = []; _jipt.push(['project', 'homarr_labs']);`}
</Script>
</>
);
};

View File

@@ -19,6 +19,7 @@ import {
import type { RouterOutputs } from "@homarr/api";
import { signOut, useSession } from "@homarr/auth/client";
import { hotkeys } from "@homarr/definitions";
import { createModal, useModalAction } from "@homarr/modals";
import { useScopedI18n } from "@homarr/translation/client";
@@ -34,7 +35,7 @@ interface UserAvatarMenuProps {
export const UserAvatarMenu = ({ children, availableUpdatesPromise }: UserAvatarMenuProps) => {
const t = useScopedI18n("common.userAvatar.menu");
const { colorScheme, toggleColorScheme } = useMantineColorScheme();
useHotkeys([["mod+J", toggleColorScheme]]);
useHotkeys([[hotkeys.toggleColorScheme, toggleColorScheme]]);
const ColorSchemeIcon = colorScheme === "dark" ? IconSun : IconMoon;

View File

@@ -39,7 +39,7 @@
"@homarr/widgets": "workspace:^0.1.0",
"dayjs": "^1.11.18",
"dotenv": "^17.2.2",
"fastify": "^5.6.0",
"fastify": "^5.6.1",
"superjson": "2.2.2",
"undici": "7.16.0"
},
@@ -47,7 +47,7 @@
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node": "^22.18.6",
"@types/node": "^22.18.7",
"dotenv-cli": "^10.0.0",
"esbuild": "^0.25.10",
"eslint": "^9.36.0",

View File

@@ -43,8 +43,8 @@
"@semantic-release/npm": "^12.0.2",
"@semantic-release/release-notes-generator": "^14.1.0",
"@testcontainers/redis": "^11.6.0",
"@turbo/gen": "^2.5.6",
"@vitejs/plugin-react": "^5.0.3",
"@turbo/gen": "^2.5.8",
"@vitejs/plugin-react": "^5.0.4",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4",
"conventional-changelog-conventionalcommits": "^9.1.0",
@@ -53,14 +53,14 @@
"prettier": "^3.6.2",
"semantic-release": "^24.2.9",
"testcontainers": "^11.6.0",
"turbo": "^2.5.6",
"turbo": "^2.5.8",
"typescript": "^5.9.2",
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4"
},
"packageManager": "pnpm@10.17.0",
"packageManager": "pnpm@10.17.1",
"engines": {
"node": ">=22.19.0"
"node": ">=22.20.0"
},
"pnpm": {
"onlyBuiltDependencies": [
@@ -82,13 +82,13 @@
"brace-expansion@>=1.0.0 <=1.1.11": ">=4.0.1",
"esbuild@<=0.24.2": ">=0.25.10",
"form-data@>=4.0.0 <4.0.4": ">=4.0.4",
"hono@<4.6.5": ">=4.9.8",
"hono@<4.6.5": ">=4.9.9",
"linkifyjs@<4.3.2": ">=4.3.2",
"nanoid@>=4.0.0 <5.0.9": ">=5.1.5",
"nanoid@>=4.0.0 <5.0.9": ">=5.1.6",
"prismjs@<1.30.0": ">=1.30.0",
"proxmox-api>undici": "7.16.0",
"react-is": "^19.1.1",
"rollup@>=4.0.0 <4.22.4": ">=4.52.2",
"rollup@>=4.0.0 <4.22.4": ">=4.52.3",
"sha.js@<=2.4.11": ">=2.4.12",
"tar-fs@>=3.0.0 <3.0.9": ">=3.1.1",
"tar-fs@>=2.0.0 <2.1.3": ">=3.1.1",

View File

@@ -42,13 +42,13 @@
"@homarr/server-settings": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@kubernetes/client-node": "^1.3.0",
"@tanstack/react-query": "^5.89.0",
"@trpc/client": "^11.5.1",
"@trpc/react-query": "^11.5.1",
"@trpc/server": "^11.5.1",
"@trpc/tanstack-react-query": "^11.5.1",
"@tanstack/react-query": "^5.90.2",
"@trpc/client": "^11.6.0",
"@trpc/react-query": "^11.6.0",
"@trpc/server": "^11.6.0",
"@trpc/tanstack-react-query": "^11.6.0",
"lodash.clonedeep": "^4.5.0",
"next": "15.5.3",
"next": "15.5.4",
"react": "19.1.1",
"react-dom": "19.1.1",
"superjson": "2.2.2",

View File

@@ -55,34 +55,47 @@ export const mediaRouter = createTRPCRouter({
.requiresPermission("media-upload")
.input(mediaUploadSchema)
.mutation(async ({ ctx, input }) => {
const content = Buffer.from(await input.file.arrayBuffer());
const id = createId();
const media = {
id,
creatorId: ctx.session.user.id,
content,
size: input.file.size,
contentType: input.file.type,
name: input.file.name,
} satisfies InferInsertModel<typeof medias>;
await ctx.db.insert(medias).values(media);
const files = await Promise.all(
input.files.map(async (file) => ({
id: createId(),
meta: file,
content: Buffer.from(await file.arrayBuffer()),
})),
);
const insertMedias = files.map(
(file): InferInsertModel<typeof medias> => ({
id: file.id,
creatorId: ctx.session.user.id,
content: file.content,
size: file.meta.size,
contentType: file.meta.type,
name: file.meta.name,
}),
);
await ctx.db.insert(medias).values(insertMedias);
const localIconRepository = await ctx.db.query.iconRepositories.findFirst({
where: eq(iconRepositories.slug, LOCAL_ICON_REPOSITORY_SLUG),
});
if (!localIconRepository) return id;
const ids = files.map((file) => file.id);
if (!localIconRepository) return ids;
const icon = mapMediaToIcon(media);
await ctx.db.insert(icons).values({
id: createId(),
checksum: icon.checksum,
name: icon.fileNameWithExtension,
url: icon.imageUrl,
iconRepositoryId: localIconRepository.id,
});
await ctx.db.insert(icons).values(
insertMedias.map((media) => {
const icon = mapMediaToIcon(media);
return id;
return {
id: createId(),
checksum: icon.checksum,
name: icon.fileNameWithExtension,
url: icon.imageUrl,
iconRepositoryId: localIconRepository.id,
};
}),
);
return ids;
}),
deleteMedia: protectedProcedure.input(byIdSchema).mutation(async ({ ctx, input }) => {
const dbMedia = await ctx.db.query.medias.findFirst({

View File

@@ -1,4 +1,7 @@
import { observable } from "@trpc/server/observable";
import { getIntegrationKindsByCategory } from "@homarr/definitions";
import type { MediaTranscoding } from "@homarr/request-handler/media-transcoding";
import { mediaTranscodingRequestHandler } from "@homarr/request-handler/media-transcoding";
import { paginatedSchema } from "@homarr/validation/common";
@@ -15,7 +18,7 @@ export const mediaTranscodingRouter = createTRPCRouter({
.input(paginatedSchema.pick({ page: true, pageSize: true }))
.query(async ({ ctx, input }) => {
const innerHandler = mediaTranscodingRequestHandler.handler(ctx.integration, {
pageOffset: input.page,
pageOffset: (input.page - 1) * input.pageSize,
pageSize: input.pageSize,
});
const { data } = await innerHandler.getCachedOrUpdatedDataAsync({ forceUpdate: false });
@@ -25,4 +28,19 @@ export const mediaTranscodingRouter = createTRPCRouter({
data,
};
}),
subscribeData: publicProcedure
.concat(createIndexerManagerIntegrationMiddleware("query"))
.input(paginatedSchema.pick({ page: true, pageSize: true }))
.subscription(({ ctx, input }) => {
return observable<{ integrationId: string; data: MediaTranscoding }>((emit) => {
const innerHandler = mediaTranscodingRequestHandler.handler(ctx.integration, {
pageOffset: (input.page - 1) * input.pageSize,
pageSize: input.pageSize,
});
const unsubscribe = innerHandler.subscribe((data) => {
emit.next({ integrationId: input.integrationId, data });
});
return unsubscribe;
});
}),
});

View File

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

View File

@@ -32,7 +32,7 @@
"@paralleldrive/cuid2": "^2.2.2",
"dayjs": "^1.11.18",
"dns-caching": "^0.2.7",
"next": "15.5.3",
"next": "15.5.4",
"octokit": "^5.0.3",
"react": "19.1.1",
"react-dom": "19.1.1",

View File

@@ -25,7 +25,7 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@t3-oss/env-nextjs": "^0.13.8",
"ioredis": "5.7.0",
"ioredis": "5.8.0",
"zod": "^4.1.11"
},
"devDependencies": {

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.89.0",
"@trpc/client": "^11.5.1",
"@trpc/server": "^11.5.1",
"@trpc/tanstack-react-query": "^11.5.1",
"@tanstack/react-query": "^5.90.2",
"@trpc/client": "^11.6.0",
"@trpc/server": "^11.6.0",
"@trpc/tanstack-react-query": "^11.6.0",
"node-cron": "^4.2.1",
"react": "19.1.1",
"zod": "^4.1.11"
@@ -42,7 +42,7 @@
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-cron": "^3.0.11",
"@types/react": "19.1.13",
"@types/react": "19.1.15",
"eslint": "^9.36.0",
"typescript": "^5.9.2"
}

View File

@@ -49,16 +49,16 @@
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/core": "^8.3.1",
"@mantine/core": "^8.3.2",
"@paralleldrive/cuid2": "^2.2.2",
"@testcontainers/mysql": "^11.6.0",
"@testcontainers/postgresql": "^11.6.0",
"better-sqlite3": "^12.2.0",
"better-sqlite3": "^12.4.1",
"dotenv": "^17.2.2",
"drizzle-kit": "^0.31.4",
"drizzle-kit": "^0.31.5",
"drizzle-orm": "^0.44.5",
"drizzle-zod": "^0.8.3",
"mysql2": "3.15.0",
"mysql2": "3.15.1",
"pg": "^8.16.3",
"superjson": "2.2.2"
},

View File

@@ -0,0 +1,6 @@
export const hotkeys = {
toggleBoardEdit: "mod+e",
toggleColorScheme: "mod+j",
saveNotebook: "mod+s",
openSpotlight: "mod+k",
};

View File

@@ -13,3 +13,4 @@ export * from "./cookie";
export * from "./search-engine";
export * from "./onboarding";
export * from "./emptysuperjson";
export * from "./hotkeys";

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.3.1",
"@mantine/form": "^8.3.2",
"mantine-form-zod-resolver": "^1.3.0",
"zod": "^4.1.11"
},

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.3.1",
"@mantine/core": "^8.3.2",
"react": "19.1.1",
"zod": "^4.1.11"
},

View File

@@ -165,11 +165,14 @@ export const IconPicker = ({
/>
{session?.user.permissions.includes("media-upload") && (
<UploadMedia
onSuccess={({ url }) => {
onSuccess={(medias) => {
const first = medias.at(0);
if (!first) return;
startTransition(() => {
setValue(url);
setPreviewUrl(url);
setSearch(url);
setValue(first.url);
setPreviewUrl(first.url);
setSearch(first.url);
});
}}
>

View File

@@ -9,27 +9,31 @@ import { supportedMediaUploadFormats } from "@homarr/validation/media";
interface UploadMediaProps {
children: (props: { onClick: () => void; loading: boolean }) => JSX.Element;
multiple?: boolean;
onSettled?: () => MaybePromise<void>;
onSuccess?: (media: { id: string; url: string }) => MaybePromise<void>;
onSuccess?: (media: { id: string; url: string }[]) => MaybePromise<void>;
}
export const UploadMedia = ({ children, onSettled, onSuccess }: UploadMediaProps) => {
export const UploadMedia = ({ children, onSettled, onSuccess, multiple = false }: UploadMediaProps) => {
const t = useI18n();
const { mutateAsync, isPending } = clientApi.media.uploadMedia.useMutation();
const handleFileUploadAsync = async (file: File | null) => {
if (!file) return;
const handleFileUploadAsync = async (files: File[] | File | null) => {
if (!files || (Array.isArray(files) && files.length === 0)) return;
const filesArray: File[] = Array.isArray(files) ? files : [files];
const formData = new FormData();
formData.append("file", file);
filesArray.forEach((file) => formData.append("files", file));
await mutateAsync(formData, {
async onSuccess(mediaId) {
async onSuccess(mediaIds) {
showSuccessNotification({
message: t("media.action.upload.notification.success.message"),
});
await onSuccess?.({
id: mediaId,
url: `/api/user-medias/${mediaId}`,
});
await onSuccess?.(
mediaIds.map((id) => ({
id,
url: `/api/user-medias/${id}`,
})),
);
},
onError() {
showErrorNotification({
@@ -43,7 +47,7 @@ export const UploadMedia = ({ children, onSettled, onSuccess }: UploadMediaProps
};
return (
<FileButton onChange={handleFileUploadAsync} accept={supportedMediaUploadFormats.join(",")}>
<FileButton onChange={handleFileUploadAsync} accept={supportedMediaUploadFormats.join(",")} multiple={multiple}>
{({ onClick }) => children({ onClick, loading: isPending })}
</FileButton>
);

View File

@@ -117,6 +117,7 @@ export class EmbyIntegration extends Integration implements IMediaServerIntegrat
episodeName: sessionInfo.NowPlayingItem.EpisodeTitle,
albumName: sessionInfo.NowPlayingItem.Album ?? "",
episodeCount: sessionInfo.NowPlayingItem.EpisodeCount,
metadata: null,
};
}

View File

@@ -13,6 +13,30 @@ export interface StreamSession {
episodeName?: string | null;
albumName?: string | null;
episodeCount?: number | null;
metadata: {
video: {
resolution: {
width: number;
height: number;
} | null;
frameRate: number | null;
};
audio: {
channelCount: number | null;
codec: string | null;
};
transcoding: {
container: string | null;
resolution: {
width: number;
height: number;
} | null;
target: {
audioCodec: string | null;
videoCodec: string | null;
};
};
} | null;
} | null;
}

View File

@@ -57,6 +57,36 @@ export class JellyfinIntegration extends Integration implements IMediaServerInte
episodeName: sessionInfo.NowPlayingItem.EpisodeTitle,
albumName: sessionInfo.NowPlayingItem.Album ?? "",
episodeCount: sessionInfo.NowPlayingItem.EpisodeCount,
metadata: {
video: {
resolution:
sessionInfo.NowPlayingItem.Width && sessionInfo.NowPlayingItem.Height
? {
width: sessionInfo.NowPlayingItem.Width,
height: sessionInfo.NowPlayingItem.Height,
}
: null,
frameRate: sessionInfo.TranscodingInfo?.Framerate ?? null,
},
audio: {
channelCount: sessionInfo.TranscodingInfo?.AudioChannels ?? null,
codec: sessionInfo.TranscodingInfo?.AudioCodec ?? null,
},
transcoding: {
resolution:
sessionInfo.TranscodingInfo?.Width && sessionInfo.TranscodingInfo.Height
? {
width: sessionInfo.TranscodingInfo.Width,
height: sessionInfo.TranscodingInfo.Height,
}
: null,
target: {
audioCodec: sessionInfo.TranscodingInfo?.AudioCodec ?? null,
videoCodec: sessionInfo.TranscodingInfo?.VideoCodec ?? null,
},
container: sessionInfo.TranscodingInfo?.Container ?? null,
},
},
};
}

View File

@@ -28,6 +28,7 @@ export class MediaServerMockService implements IMediaServerIntegration {
episodeName: null,
albumName: null,
episodeCount: null,
metadata: null,
}
: null,
};

View File

@@ -61,6 +61,7 @@ export class PlexIntegration extends Integration implements IMediaServerIntegrat
episodeName: mediaElement.$.title ?? null,
albumName: mediaElement.$.type === "track" ? (mediaElement.$.parentTitle ?? null) : null,
episodeCount: mediaElement.$.index ?? null,
metadata: null,
},
};
})

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.3.1",
"@mantine/core": "^8.3.2",
"@tabler/icons-react": "^3.35.0",
"dayjs": "^1.11.18",
"next": "15.5.3",
"next": "15.5.4",
"react": "19.1.1",
"react-dom": "19.1.1",
"zod": "^4.1.11"

View File

@@ -24,8 +24,8 @@
"dependencies": {
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.3.1",
"@mantine/hooks": "^8.3.1",
"@mantine/core": "^8.3.2",
"@mantine/hooks": "^8.3.2",
"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.3.1",
"@mantine/notifications": "^8.3.2",
"@tabler/icons-react": "^3.35.0"
},
"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.3.1",
"@mantine/hooks": "^8.3.1",
"@mantine/core": "^8.3.2",
"@mantine/hooks": "^8.3.2",
"adm-zip": "0.5.16",
"next": "15.5.3",
"next": "15.5.4",
"react": "19.1.1",
"react-dom": "19.1.1",
"superjson": "2.2.2",

View File

@@ -27,7 +27,7 @@
"@homarr/db": "workspace:^",
"@homarr/definitions": "workspace:^",
"@homarr/log": "workspace:^",
"ioredis": "5.7.0",
"ioredis": "5.8.0",
"superjson": "2.2.2"
},
"devDependencies": {

View File

@@ -7,7 +7,7 @@ import type { TdarrQueue, TdarrStatistics, TdarrWorker } from "@homarr/integrati
import { createCachedIntegrationRequestHandler } from "./lib/cached-integration-request-handler";
export const mediaTranscodingRequestHandler = createCachedIntegrationRequestHandler<
{ queue: TdarrQueue; workers: TdarrWorker[]; statistics: TdarrStatistics },
MediaTranscoding,
IntegrationKindByCategory<"mediaTranscoding">,
{ pageOffset: number; pageSize: number }
>({
@@ -22,3 +22,9 @@ export const mediaTranscodingRequestHandler = createCachedIntegrationRequestHand
};
},
});
export interface MediaTranscoding {
queue: TdarrQueue;
workers: TdarrWorker[];
statistics: TdarrStatistics;
}

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.3.1",
"next": "15.5.3",
"@mantine/dates": "^8.3.2",
"next": "15.5.4",
"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.3.1",
"@mantine/hooks": "^8.3.1",
"@mantine/spotlight": "^8.3.1",
"@mantine/core": "^8.3.2",
"@mantine/hooks": "^8.3.2",
"@mantine/spotlight": "^8.3.2",
"@tabler/icons-react": "^3.35.0",
"jotai": "^2.14.0",
"next": "15.5.3",
"jotai": "^2.15.0",
"next": "15.5.4",
"react": "19.1.1",
"react-dom": "19.1.1",
"use-deep-compare-effect": "^1.8.1"

View File

@@ -6,6 +6,7 @@ import { ActionIcon, Center, Group, Kbd } from "@mantine/core";
import { Spotlight as MantineSpotlight } from "@mantine/spotlight";
import { IconQuestionMark, IconSearch, IconX } from "@tabler/icons-react";
import { hotkeys } from "@homarr/definitions";
import type { TranslationObject } from "@homarr/translation";
import { useI18n } from "@homarr/translation/client";
@@ -49,6 +50,7 @@ const SpotlightWithActiveMode = ({ modeState, activeMode }: SpotlightWithActiveM
return (
<MantineSpotlight.Root
shortcut={hotkeys.openSpotlight}
yOffset={8}
onSpotlightClose={() => {
setMode(defaultMode);

View File

@@ -3,6 +3,7 @@ import { IconCheck } from "@tabler/icons-react";
import { localeConfigurations, supportedLanguages } from "@homarr/translation";
import { useChangeLocale, useCurrentLocale, useI18n } from "@homarr/translation/client";
import { LanguageIcon } from "@homarr/ui";
import { createChildrenOptions } from "../../../lib/children";
@@ -34,7 +35,7 @@ export const languageChildrenOptions = createChildrenOptions<Record<string, unkn
return (
<Group mx="md" my="sm" wrap="nowrap" justify="space-between" w="100%">
<Group wrap="nowrap">
<span className={`fi fi-${configuration.flagIcon}`} style={{ borderRadius: 4 }}></span>
<LanguageIcon icon={localeConfigurations[localeKey].icon} />
<Group wrap="nowrap" gap="xs">
<Text>{configuration.name}</Text>
<Text size="xs" c="dimmed" inherit>

View File

@@ -32,7 +32,7 @@
"dayjs": "^1.11.18",
"deepmerge": "4.3.1",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.5.3",
"next": "15.5.4",
"next-intl": "4.3.9",
"react": "19.1.1",
"react-dom": "19.1.1"

View File

@@ -6,7 +6,7 @@ export const localeConfigurations = {
ca: {
name: "Català",
translatedName: "Catalan",
flagIcon: "es-ct",
icon: flagIcon("es-ct"),
importMrtLocalization() {
return import("./mantine-react-table/ca.json");
},
@@ -17,7 +17,7 @@ export const localeConfigurations = {
cn: {
name: "中文",
translatedName: "Chinese (Simplified)",
flagIcon: "cn",
icon: flagIcon("cn"),
importMrtLocalization() {
return import("mantine-react-table/locales/zh-Hans/index.esm.mjs").then(
(module) => module.MRT_Localization_ZH_HANS,
@@ -27,10 +27,24 @@ export const localeConfigurations = {
return import("dayjs/locale/zh-cn").then((module) => module.default);
},
},
cr: {
name: "Crowdin",
translatedName: "Live translation",
icon: {
type: "custom" as const,
url: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/crowdin.svg",
},
importMrtLocalization() {
return import("mantine-react-table/locales/en/index.esm.mjs").then((module) => module.MRT_Localization_EN);
},
importDayJsLocale() {
return import("dayjs/locale/en-gb").then((module) => module.default);
},
},
cs: {
name: "Čeština",
translatedName: "Czech",
flagIcon: "cz",
icon: flagIcon("cz"),
importMrtLocalization() {
return import("mantine-react-table/locales/cs/index.esm.mjs").then((module) => module.MRT_Localization_CS);
},
@@ -41,7 +55,7 @@ export const localeConfigurations = {
da: {
name: "Dansk",
translatedName: "Danish",
flagIcon: "dk",
icon: flagIcon("dk"),
importMrtLocalization() {
return import("mantine-react-table/locales/da/index.esm.mjs").then((module) => module.MRT_Localization_DA);
},
@@ -52,7 +66,7 @@ export const localeConfigurations = {
de: {
name: "Deutsch",
translatedName: "German",
flagIcon: "de",
icon: flagIcon("de"),
importMrtLocalization() {
return import("mantine-react-table/locales/de/index.esm.mjs").then((module) => module.MRT_Localization_DE);
},
@@ -63,7 +77,7 @@ export const localeConfigurations = {
"de-CH": {
name: "Deutsch (Schweiz)",
translatedName: "German (Swiss)",
flagIcon: "ch",
icon: flagIcon("ch"),
importMrtLocalization() {
return import("mantine-react-table/locales/de/index.esm.mjs").then((module) => module.MRT_Localization_DE);
},
@@ -74,7 +88,7 @@ export const localeConfigurations = {
"en-gb": {
name: "English (UK)",
translatedName: "English (UK)",
flagIcon: "gb",
icon: flagIcon("gb"),
importMrtLocalization() {
return import("mantine-react-table/locales/en/index.esm.mjs").then((module) => module.MRT_Localization_EN);
},
@@ -85,7 +99,7 @@ export const localeConfigurations = {
en: {
name: "English (US)",
translatedName: "English (US)",
flagIcon: "us",
icon: flagIcon("us"),
importMrtLocalization() {
return import("mantine-react-table/locales/en/index.esm.mjs").then((module) => module.MRT_Localization_EN);
},
@@ -96,7 +110,7 @@ export const localeConfigurations = {
el: {
name: "Ελληνικά",
translatedName: "Greek",
flagIcon: "gr",
icon: flagIcon("gr"),
importMrtLocalization() {
return import("mantine-react-table/locales/el/index.esm.mjs").then((module) => module.MRT_Localization_EL);
},
@@ -107,7 +121,7 @@ export const localeConfigurations = {
es: {
name: "Español",
translatedName: "Spanish",
flagIcon: "es",
icon: flagIcon("es"),
importMrtLocalization() {
return import("mantine-react-table/locales/es/index.esm.mjs").then((module) => module.MRT_Localization_ES);
},
@@ -118,7 +132,7 @@ export const localeConfigurations = {
et: {
name: "Eesti",
translatedName: "Estonian",
flagIcon: "ee",
icon: flagIcon("ee"),
importMrtLocalization() {
return import("mantine-react-table/locales/et/index.esm.mjs").then((module) => module.MRT_Localization_ET);
},
@@ -129,7 +143,7 @@ export const localeConfigurations = {
fr: {
name: "Français",
translatedName: "French",
flagIcon: "fr",
icon: flagIcon("fr"),
importMrtLocalization() {
return import("mantine-react-table/locales/fr/index.esm.mjs").then((module) => module.MRT_Localization_FR);
},
@@ -140,7 +154,7 @@ export const localeConfigurations = {
he: {
name: "עברית",
translatedName: "Hebrew",
flagIcon: "il",
icon: flagIcon("il"),
isRTL: true,
importMrtLocalization() {
return import("mantine-react-table/locales/he/index.esm.mjs").then((module) => module.MRT_Localization_HE);
@@ -152,7 +166,7 @@ export const localeConfigurations = {
hr: {
name: "Hrvatski",
translatedName: "Croatian",
flagIcon: "hr",
icon: flagIcon("hr"),
importMrtLocalization() {
return import("mantine-react-table/locales/hr/index.esm.mjs").then((module) => module.MRT_Localization_HR);
},
@@ -163,7 +177,7 @@ export const localeConfigurations = {
hu: {
name: "Magyar",
translatedName: "Hungarian",
flagIcon: "hu",
icon: flagIcon("hu"),
importMrtLocalization() {
return import("mantine-react-table/locales/hu/index.esm.mjs").then((module) => module.MRT_Localization_HU);
},
@@ -174,7 +188,7 @@ export const localeConfigurations = {
it: {
name: "Italiano",
translatedName: "Italian",
flagIcon: "it",
icon: flagIcon("it"),
importMrtLocalization() {
return import("mantine-react-table/locales/it/index.esm.mjs").then((module) => module.MRT_Localization_IT);
},
@@ -185,7 +199,7 @@ export const localeConfigurations = {
ja: {
name: "日本語",
translatedName: "Japanese",
flagIcon: "jp",
icon: flagIcon("jp"),
importMrtLocalization() {
return import("mantine-react-table/locales/ja/index.esm.mjs").then((module) => module.MRT_Localization_JA);
},
@@ -196,7 +210,7 @@ export const localeConfigurations = {
ko: {
name: "한국어",
translatedName: "Korean",
flagIcon: "kr",
icon: flagIcon("kr"),
importMrtLocalization() {
return import("mantine-react-table/locales/ko/index.esm.mjs").then((module) => module.MRT_Localization_KO);
},
@@ -207,7 +221,7 @@ export const localeConfigurations = {
lt: {
name: "Lietuvių",
translatedName: "Lithuanian",
flagIcon: "lt",
icon: flagIcon("lt"),
importMrtLocalization() {
return import("./mantine-react-table/lt.json");
},
@@ -218,7 +232,7 @@ export const localeConfigurations = {
lv: {
name: "Latviešu",
translatedName: "Latvian",
flagIcon: "lv",
icon: flagIcon("lv"),
importMrtLocalization() {
return import("./mantine-react-table/lv.json");
},
@@ -229,7 +243,7 @@ export const localeConfigurations = {
nl: {
name: "Nederlands",
translatedName: "Dutch",
flagIcon: "nl",
icon: flagIcon("nl"),
importMrtLocalization() {
return import("mantine-react-table/locales/nl/index.esm.mjs").then((module) => module.MRT_Localization_NL);
},
@@ -240,7 +254,7 @@ export const localeConfigurations = {
no: {
name: "Norsk",
translatedName: "Norwegian",
flagIcon: "no",
icon: flagIcon("no"),
importMrtLocalization() {
return import("mantine-react-table/locales/no/index.esm.mjs").then((module) => module.MRT_Localization_NO);
},
@@ -251,7 +265,7 @@ export const localeConfigurations = {
pl: {
name: "Polski",
translatedName: "Polish",
flagIcon: "pl",
icon: flagIcon("pl"),
importMrtLocalization() {
return import("mantine-react-table/locales/pl/index.esm.mjs").then((module) => module.MRT_Localization_PL);
},
@@ -262,7 +276,7 @@ export const localeConfigurations = {
pt: {
name: "Português",
translatedName: "Portuguese",
flagIcon: "pt",
icon: flagIcon("pt"),
importMrtLocalization() {
return import("mantine-react-table/locales/pt/index.esm.mjs").then((module) => module.MRT_Localization_PT);
},
@@ -273,7 +287,7 @@ export const localeConfigurations = {
ro: {
name: "Românesc",
translatedName: "Romanian",
flagIcon: "ro",
icon: flagIcon("ro"),
importMrtLocalization() {
return import("mantine-react-table/locales/ro/index.esm.mjs").then((module) => module.MRT_Localization_RO);
},
@@ -284,7 +298,7 @@ export const localeConfigurations = {
ru: {
name: "Русский",
translatedName: "Russian",
flagIcon: "ru",
icon: flagIcon("ru"),
importMrtLocalization() {
return import("mantine-react-table/locales/ru/index.esm.mjs").then((module) => module.MRT_Localization_RU);
},
@@ -295,7 +309,7 @@ export const localeConfigurations = {
sk: {
name: "Slovenčina",
translatedName: "Slovak",
flagIcon: "sk",
icon: flagIcon("sk"),
importMrtLocalization() {
return import("mantine-react-table/locales/sk/index.esm.mjs").then((module) => module.MRT_Localization_SK);
},
@@ -306,7 +320,7 @@ export const localeConfigurations = {
sl: {
name: "Slovenščina",
translatedName: "Slovenian",
flagIcon: "si",
icon: flagIcon("si"),
importMrtLocalization() {
return import("./mantine-react-table/sl.json");
},
@@ -317,7 +331,7 @@ export const localeConfigurations = {
sv: {
name: "Svenska",
translatedName: "Swedish",
flagIcon: "se",
icon: flagIcon("se"),
importMrtLocalization() {
return import("mantine-react-table/locales/sv/index.esm.mjs").then((module) => module.MRT_Localization_SV);
},
@@ -328,7 +342,7 @@ export const localeConfigurations = {
tr: {
name: "Türkçe",
translatedName: "Turkish",
flagIcon: "tr",
icon: flagIcon("tr"),
importMrtLocalization() {
return import("mantine-react-table/locales/tr/index.esm.mjs").then((module) => module.MRT_Localization_TR);
},
@@ -339,7 +353,7 @@ export const localeConfigurations = {
zh: {
name: "中文",
translatedName: "Chinese (Traditional)",
flagIcon: "tw",
icon: flagIcon("tw"),
importMrtLocalization() {
return import("mantine-react-table/locales/zh-Hant/index.esm.mjs").then(
(module) => module.MRT_Localization_ZH_HANT,
@@ -352,7 +366,7 @@ export const localeConfigurations = {
uk: {
name: "Українська",
translatedName: "Ukrainian",
flagIcon: "ua",
icon: flagIcon("ua"),
importMrtLocalization() {
return import("mantine-react-table/locales/uk/index.esm.mjs").then((module) => module.MRT_Localization_UK);
},
@@ -363,7 +377,7 @@ export const localeConfigurations = {
vi: {
name: "Tiếng Việt",
translatedName: "Vietnamese",
flagIcon: "vn",
icon: flagIcon("vn"),
importMrtLocalization() {
return import("mantine-react-table/locales/vi/index.esm.mjs").then((module) => module.MRT_Localization_VI);
},
@@ -376,13 +390,27 @@ export const localeConfigurations = {
{
name: string;
translatedName: string;
flagIcon: string;
icon: LanguageIconDefinition;
importMrtLocalization: () => Promise<MRT_Localization>;
importDayJsLocale: () => Promise<ILocale>;
isRTL?: boolean;
}
>;
function flagIcon<TCode extends string>(flag: TCode) {
return { type: "flag" as const, flag };
}
export type LanguageIconDefinition =
| {
type: "flag";
flag: string;
}
| {
type: "custom";
url: string;
};
export const supportedLanguages = objectKeys(localeConfigurations);
export type SupportedLanguage = (typeof supportedLanguages)[number];

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "",
"height": ""
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,25 +945,29 @@
"label": "主题",
"newLabel": "新主题"
},
"url": {
"label": "网址",
"newLabel": "新网址"
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
"label": "API 密钥 (Key)",
"newLabel": "新 API 密钥 (Key)"
},
"opnsenseApiSecret": {
"label": "",
"newLabel": ""
"label": "API 密钥 (保密)",
"newLabel": "新 API 密钥 (保密)"
},
"githubAppId": {
"label": "",
"newLabel": ""
"label": "应用ID",
"newLabel": "新应用ID"
},
"githubInstallationId": {
"label": "",
"newLabel": ""
"label": "安装 ID",
"newLabel": "新安装 ID"
},
"privateKey": {
"label": "",
"newLabel": ""
"label": "私人密钥",
"newLabel": "新私人密钥"
}
}
},
@@ -1015,7 +1019,7 @@
}
},
"common": {
"success": "",
"success": "成功",
"beta": "测试版",
"error": "错误",
"action": {
@@ -1282,21 +1286,21 @@
"label": "启用状态检查"
},
"layout": {
"label": "",
"label": "界面",
"option": {
"row": "",
"row-reverse": "",
"column": "",
"column-reverse": ""
"row": "横向",
"row-reverse": "横向 (反转)",
"column": "垂直",
"column-reverse": "垂直 (反转)"
}
},
"descriptionDisplayMode": {
"label": "",
"description": "",
"label": "描述信息显示模式",
"description": "选择应用描述的显示方式",
"option": {
"normal": "",
"tooltip": "",
"hidden": ""
"normal": "窗口组件内",
"tooltip": "显示为悬停提示",
"hidden": "隐藏"
}
}
},
@@ -1543,7 +1547,15 @@
"width": "宽度",
"height": "高度"
},
"placeholder": "开始写笔记"
"placeholder": "开始写笔记",
"dismiss": {
"title": "是否放弃修改?",
"message": "仍有未保存的更改,确定要丢弃吗?",
"action": {
"discard": "放弃修改",
"keepEditing": "继续编辑"
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "日历",
"description": "在日历视图中显示某个相对时间段内的集成事件",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr 发布类型",
@@ -2273,7 +2288,7 @@
"label": "帖子数量限制"
},
"hideDescription": {
"label": ""
"label": "隐藏描述"
}
}
},
@@ -2488,9 +2503,31 @@
"option": {}
},
"systemResources": {
"name": "",
"name": "系统资源",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "CPU",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": "防火墙接口"
},
"weather": {
"label": ""
}
},
"interval": {
@@ -3303,7 +3343,7 @@
},
"field": {
"name": {
"label": ""
"label": "名称"
},
"interval": {
"label": "计划时间间隔"

File diff suppressed because it is too large Load Diff

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Šířka",
"height": "Výška"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalendář",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Typ vydání filmu pro Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "Emne",
"newLabel": "Nyt emne"
},
"url": {
"label": "Url",
"newLabel": "Ny Url"
},
"opnsenseApiKey": {
"label": "API-nøgle (Key)",
"newLabel": "Ny API-nøgle (Key)"
@@ -954,16 +958,16 @@
"newLabel": "Ny API-nøgle (Key)"
},
"githubAppId": {
"label": "",
"newLabel": ""
"label": "App Id",
"newLabel": "Nyt App Id"
},
"githubInstallationId": {
"label": "",
"newLabel": ""
"label": "Installations Id",
"newLabel": "Nyt Installations Id"
},
"privateKey": {
"label": "",
"newLabel": ""
"label": "Privat nøgle",
"newLabel": "Ny privat nøgle"
}
}
},
@@ -1543,7 +1547,15 @@
"width": "Bredde",
"height": "Højde"
},
"placeholder": "Begynd at skrive dine noter"
"placeholder": "Begynd at skrive dine noter",
"dismiss": {
"title": "Annuller ændringer?",
"message": "Du har ugemte ændringer i din notesbog. Er du sikker på, at du vil kassere dem?",
"action": {
"discard": "Fortryd ændringer",
"keepEditing": "Fortsæt redigering"
}
}
},
"iframe": {
"name": "indlejret dokument (iframe)",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalender",
"description": "Vis begivenheder fra dine integrationer i en kalendervisning inden for en vis relativ tidsperiode",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr udgivelsestype",
@@ -2273,7 +2288,7 @@
"label": "Grænse for antal indlæg"
},
"hideDescription": {
"label": ""
"label": "Skjul beskrivelse"
}
}
},
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "Systemressourcer",
"description": "CPU, Hukommelse, Disk og andet hardwareforbrug af dit system",
"option": {},
"option": {
"hasShadow": {
"label": "Aktiver diagramskygge"
},
"visibleCharts": {
"label": "Synlige diagrammer",
"description": "Vælg de diagrammer, du ønsker at være synlige.",
"option": {
"cpu": "CPU",
"memory": "Hukommelse",
"network": "Netværk"
}
},
"labelDisplayMode": {
"label": "Label visningstilstand",
"option": {
"textWithIcon": "Vis tekst med ikon",
"text": "Vis kun tekst",
"icon": "Vis kun ikonet",
"hidden": "Skjul etiket"
}
}
},
"card": {
"cpu": "CPU",
"memory": "MEM",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": "Firewall Grænseflader"
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Breite",
"height": "Höhe"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalender",
"description": "Zeigt Ereignisse aus Ihren Integrationen in einer Kalenderansicht innerhalb eines bestimmten Zeitraums an",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr Veröffentlichungs Typ",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "Thema",
"newLabel": "Neues Thema erstellen"
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Breite",
"height": "Höhe"
},
"placeholder": "Mit dem Schreiben von Notizen beginnen"
"placeholder": "Mit dem Schreiben von Notizen beginnen",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalender",
"description": "Zeigt Ereignisse aus Ihren Integrationen in einer Kalenderansicht innerhalb eines bestimmten Zeitraums an",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr Veröffentlichungs Typ",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "Systemressourcen",
"description": "CPU, Arbeitsspeicher, Festplatte und andere Hardware-Nutzung Ihres Systems",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "CPU",
"memory": "Arbeitsspeicher",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": "Firewall Schnittstellen"
},
"weather": {
"label": "Wetter"
}
},
"interval": {
@@ -3303,24 +3343,24 @@
},
"field": {
"name": {
"label": ""
"label": "Name"
},
"interval": {
"label": "Intervall des Zeitplans"
},
"lastExecution": {
"label": ""
"label": "Letzte Ausführung"
},
"actions": {
"label": ""
"label": "Aktionen"
}
},
"table": {
"search": ""
"search": "{count} Aufgaben suchen..."
},
"action": {
"refresh": {
"label": ""
"label": "Neu laden"
}
},
"refresh": {
@@ -3861,7 +3901,7 @@
"tools": {
"label": "Werkzeuge",
"tasks": {
"label": ""
"label": "Aufgaben"
},
"docker": {
"label": "Docker"

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Πλάτος",
"height": "Ύψος"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iframe",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Ημερολόγιο",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Τύπος κυκλοφορίας Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "",
"height": ""
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -1980,7 +1980,25 @@
"currentlyPlaying": "Currently playing",
"user": "User",
"name": "Name",
"id": "Id"
"id": "Id",
"metadata": {
"title": "Stats for nerds",
"video": {
"title": "Video",
"resolution": "Resolution"
},
"audio": {
"title": "Audio",
"channelCount": "Audio channels",
"codec": "Audio codec"
},
"transcoding": {
"title": "Transcoding",
"container": "Container",
"resolution": "Resolution",
"target": "Target codec"
}
}
}
},
"downloads": {
@@ -3446,6 +3464,21 @@
"libraries": {
"title": "Libraries",
"subtitle": "{count} used in the Code of Homarr"
},
"hotkeys": {
"title": "Hotkeys",
"subtitle": "Keyboard shortcuts to enhance your workflow",
"field": {
"shortcut": "Shortcut",
"action": "Action"
},
"action": {
"toggleBoardEdit": "Toggle board edit mode",
"toggleColorScheme": "Toggle light/dark mode",
"saveNotebook": "Save notebook (only inside notebook widget)",
"openSpotlight": "Open search"
},
"note": "Tip: Mod refers to both Ctrl key and ⌘ key on macOS"
}
}
}

View File

@@ -945,6 +945,10 @@
"label": "Tema",
"newLabel": "Nuevo tema"
},
"url": {
"label": "URL",
"newLabel": "Nueva URL"
},
"opnsenseApiKey": {
"label": "Clave API (Clave)",
"newLabel": "Nueva clave API (Clave)"
@@ -1543,7 +1547,15 @@
"width": "Ancho",
"height": "Alto"
},
"placeholder": "Comienza a escribir tus notas"
"placeholder": "Comienza a escribir tus notas",
"dismiss": {
"title": "¿Descartar los cambios?",
"message": "Tienes cambios sin guardar en tu bloc de notas. ¿Estás seguro de que quieres descartarlos?",
"action": {
"discard": "Descartar cambios",
"keepEditing": "Seguir editando"
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Calendario",
"description": "Mostrar los eventos de tus integraciones en una vista de calendario dentro de un cierto período de tiempo",
"duration": {
"allDay": "Todo el día"
},
"option": {
"releaseType": {
"label": "Tipo de lanzamiento de Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "Recursos del sistema",
"description": "CPU, Memoria, Disco y otro uso de hardware de su sistema",
"option": {},
"option": {
"hasShadow": {
"label": "Activar sombreado de gráfico"
},
"visibleCharts": {
"label": "Gráficos visibles",
"description": "Selecciona los gráficos que quieres que sean visibles.",
"option": {
"cpu": "CPU",
"memory": "Memoria",
"network": "Red"
}
},
"labelDisplayMode": {
"label": "Modo de visualización de etiqueta",
"option": {
"textWithIcon": "Mostrar texto con icono",
"text": "Mostrar solo el texto",
"icon": "Mostrar solo el icono",
"hidden": "Ocultar etiqueta"
}
}
},
"card": {
"cpu": "CPU",
"memory": "MEM",
@@ -2925,7 +2962,7 @@
"boards": "Tableros",
"resources": "Recursos",
"authentication": "Autenticación",
"authorization": "Autorización"
"authorization": "Autenticación"
}
},
"board": {
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": "Interfaces del Firewall"
},
"weather": {
"label": "Tiempo"
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "",
"height": ""
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "Sujet",
"newLabel": "Nouveau sujet"
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Largeur",
"height": "Hauteur"
},
"placeholder": "Commencer à écrire vos notes"
"placeholder": "Commencer à écrire vos notes",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Calendrier",
"description": "Afficher les événements de vos intégrations dans une vue calendrier pendant une certaine période de temps relative",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Type de sortie Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -938,32 +938,36 @@
"newLabel": "תחום חדש"
},
"personalAccessToken": {
"label": "",
"newLabel": ""
"label": "טוקן גישה אישי",
"newLabel": "טוקן גישה אישי חדש"
},
"topic": {
"label": "נושא",
"newLabel": "נושא חדש"
},
"opnsenseApiKey": {
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "מפתח API (מפתח)",
"newLabel": "מפתח API חדש (מפתח)"
},
"opnsenseApiSecret": {
"label": "",
"newLabel": ""
"label": "מפתח API (סודי)",
"newLabel": "מפתח API חדש (סודי)"
},
"githubAppId": {
"label": "",
"newLabel": ""
"label": "מזהה אפליקציה",
"newLabel": "מזהה אפליקציה חדש"
},
"githubInstallationId": {
"label": "",
"newLabel": ""
"label": "מזהה התקנה",
"newLabel": "מזהה התקנה חדש"
},
"privateKey": {
"label": "",
"newLabel": ""
"label": "מפתח פרטי",
"newLabel": "מפתח פרטי חדש"
}
}
},
@@ -1015,7 +1019,7 @@
}
},
"common": {
"success": "",
"success": "הצלחה",
"beta": "בטא",
"error": "שגיאה",
"action": {
@@ -1282,21 +1286,21 @@
"label": "אפשר בדיקת מצב"
},
"layout": {
"label": "",
"label": "פריסה",
"option": {
"row": "",
"row-reverse": "",
"column": "",
"column-reverse": ""
"row": "אופקי",
"row-reverse": "אופקי (היפוך)",
"column": "אנכי",
"column-reverse": "אנכי (היפוך)"
}
},
"descriptionDisplayMode": {
"label": "",
"description": "",
"label": "מצב תצוגת תיאור",
"description": "בחר כיצד להציג את תיאור האפליקציה",
"option": {
"normal": "",
"tooltip": "",
"hidden": ""
"normal": "בתוך הווידג'ט",
"tooltip": "כתיאור כלים",
"hidden": "מוסתר"
}
}
},
@@ -1543,7 +1547,15 @@
"width": "רוחב",
"height": "גובה"
},
"placeholder": "התחל לכתוב את ההערות שלך"
"placeholder": "התחל לכתוב את ההערות שלך",
"dismiss": {
"title": "לבטל שינויים?",
"message": "יש לך שינויים שלא נשמרו במחברת שלך. האם אתה בטוח שברצונך למחוק אותם?",
"action": {
"discard": "בטל שינויים",
"keepEditing": "המשך לערוך"
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "לוח שנה",
"description": "הצג אירועים מהאינטגרציות שלך בתצוגת לוח שנה בתוך פרק זמן יחסי מסוים",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "סוג שחרור של Radarr",
@@ -2116,32 +2131,32 @@
"globalRatio": "יחס גלובלי"
},
"mediaReleases": {
"name": "",
"description": "",
"name": "מדיה משוחררת",
"description": "הצגת מדיה שנוספה לאחרונה או מהדורות עתידיות מאינטגרציות שונות",
"option": {
"layout": {
"label": "",
"label": "פריסה",
"option": {
"backdrop": {
"label": ""
"label": "רקע"
},
"poster": {
"label": ""
"label": "פוסטר"
}
}
},
"showDescriptionTooltip": {
"label": ""
"label": "הצג תיאור קצר"
},
"showType": {
"label": ""
"label": "הצג תג סוג מדיה"
},
"showSource": {
"label": ""
"label": "הצג שילוב מקורות"
}
},
"length": {
"duration": ""
"duration": "דקות {length}"
}
},
"mediaRequests-requestList": {
@@ -2273,7 +2288,7 @@
"label": "הגבלת כמות הודעות"
},
"hideDescription": {
"label": ""
"label": "הסתר תיאור"
}
}
},
@@ -2297,7 +2312,7 @@
"label": "הצג פרטים"
},
"showOnlyIcon": {
"label": ""
"label": "הצג רק אייקון"
},
"topReleases": {
"label": "מהדורות מובילות",
@@ -2316,8 +2331,8 @@
"listAlreadyImportedImages": "רשימת התמונות שכבר יובאו",
"allImagesAlreadyImported": "כל התמונות כבר יובאו",
"onlyAdminCanImport": "רק מנהלים יכולים לייבא מדוקר",
"selectAll": "",
"deselectAll": ""
"selectAll": "בחר הכל",
"deselectAll": "בטל בחירה של הכל"
},
"provider": {
"label": "ספק"
@@ -2367,8 +2382,8 @@
},
"invalid": "הגדרת מאגר לא חוקית, אנא בדוק את הערכים",
"noProvider": {
"label": "",
"tooltip": ""
"label": "ללא ספק",
"tooltip": "לא ניתן היה לנתח את הספק, אנא הגדר אותו ידנית לאחר ייבוא ​​התמונות"
}
}
},
@@ -2379,20 +2394,20 @@
"starsCount": "כוכבים",
"forksCount": "פיצולים",
"issuesCount": "תקלות פתוחות",
"markViewed": "",
"markViewed": "סמן כנצפה",
"openProjectPage": "פתח את דף הפרויקט",
"openReleasePage": "פתח את דף הגרסאות",
"releaseDescription": "תיאור הגרסה",
"projectDescription": "",
"projectDescription": "תיאור הפרויקט",
"created": "נוצר",
"error": {
"label": "שגיאה",
"messages": {
"invalidIdentifier": "",
"invalidIdentifier": "מזהה לא חוקי",
"noMatchingVersion": "לא נמצאה גרסה תואמת",
"noReleasesFound": "",
"noProviderSeleceted": "",
"noProviderResponse": ""
"noReleasesFound": "לא נמצאו שיחרורים",
"noProviderSeleceted": "לא נבחר ספק",
"noProviderResponse": "אין תשובה מהספק"
}
}
},
@@ -2453,31 +2468,31 @@
}
},
"firewall": {
"name": "",
"description": "",
"name": "ניטור חומת אש",
"description": "מציג סיכום של חומות אש",
"tab": {
"system": "",
"interfaces": ""
"system": "מערכת",
"interfaces": "ממשקים"
},
"error": {
"internalServerError": ""
"internalServerError": "לא ניתן לקבל נתונים מחומת האש"
},
"option": {
"interfaces": ""
"interfaces": "ממשקי רשת לתצוגה"
},
"widget": {
"fwname": "",
"version": "",
"versiontitle": "",
"cputitle": "",
"memorytitle": "",
"cpu": "",
"memory": "",
"fwname": "שם",
"version": "גרסה",
"versiontitle": "גרסאות",
"cputitle": "ניצול מעבד",
"memorytitle": "ניצול זיכרון",
"cpu": "מעבד",
"memory": "זיכרון",
"interfaces": {
"name": "",
"trans": "",
"recv": "",
"title": ""
"name": "שם",
"trans": "משודר",
"recv": "התקבל",
"title": "ממשקי רשת"
}
}
},
@@ -2488,15 +2503,37 @@
"option": {}
},
"systemResources": {
"name": "",
"description": "",
"option": {},
"name": "משאבי מערכת",
"description": "שימוש במעבד, זיכרון, דיסק וחומרה אחרת של המערכת שלך",
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "תרשימים גלויים",
"description": "בחר את התרשימים שברצונך שיהיו גלויים.",
"option": {
"cpu": "מעבד",
"memory": "זיכרון",
"network": "רשת"
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
"network": "",
"up": "",
"down": ""
"cpu": "מעבד",
"memory": "זיכרון",
"network": "רשת",
"up": "העלאה",
"down": "הורדה"
}
}
},
@@ -2685,7 +2722,7 @@
"label": "צבע סמל"
},
"clearColor": {
"label": ""
"label": "ניקוי צבע"
},
"customCss": {
"label": "עיצוב מותאם אישית עבור הלוח הזה",
@@ -3271,15 +3308,18 @@
"label": "מכולות דוקר"
},
"firewallCpu": {
"label": ""
"label": "מעבד חומת האש"
},
"firewallMemory": {
"label": ""
"label": "זיכרון חומת אש"
},
"firewallVersion": {
"label": ""
"label": "גרסת חומת אש"
},
"firewallInterfaces": {
"label": "ממשקי חומת אש"
},
"weather": {
"label": ""
}
},
@@ -3291,10 +3331,10 @@
"weeklyMonday": "כל שבוע ביום שני",
"update": {
"success": {
"message": ""
"message": "המרווח עודכן בהצלחה"
},
"error": {
"message": ""
"message": "נכשל בעדכון מרווח"
}
}
},
@@ -3303,55 +3343,55 @@
},
"field": {
"name": {
"label": ""
"label": "שם"
},
"interval": {
"label": "מרווח זמן לתזמון"
},
"lastExecution": {
"label": ""
"label": "הרצה אחרונה"
},
"actions": {
"label": ""
"label": "פעולות"
}
},
"table": {
"search": ""
"search": "חפש {count} משימות..."
},
"action": {
"refresh": {
"label": ""
"label": "רענן"
}
},
"refresh": {
"success": {
"message": ""
"message": "המשימות רעננו בהצלחה"
},
"error": {
"message": ""
"message": "רענון המשימות נכשל"
}
},
"trigger": {
"success": {
"message": ""
"message": "המשימה הופעלה בהצלחה"
},
"error": {
"message": ""
"message": "הפעלת המשימה נכשלה"
}
},
"enable": {
"success": {
"message": ""
"message": "המשימה הופעלה בהצלחה"
}
},
"disable": {
"success": {
"message": ""
"message": "המשימה הושבתה בהצלחה"
}
},
"toggle": {
"error": {
"message": ""
"message": "נכשל בהחלפת סטטוס המשימה"
}
}
},
@@ -3861,7 +3901,7 @@
"tools": {
"label": "כלים",
"tasks": {
"label": ""
"label": "משימות"
},
"docker": {
"label": "דוקר"
@@ -4391,10 +4431,10 @@
"log": {
"level": {
"option": {
"debug": "",
"info": "",
"warn": "",
"error": ""
"debug": "ניפוי באגים",
"info": "מידע",
"warn": "אזהרה",
"error": "שגיאה"
}
}
}

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Širina",
"height": "Visina"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalendar",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Vrsta izdanja u Radarr-u",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Szélesség",
"height": "Magasság"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "Beágyazott keret (iFrame)",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Naptár",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr kiadás típusa",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

File diff suppressed because it is too large Load Diff

View File

@@ -945,6 +945,10 @@
"label": "トピック",
"newLabel": "新規トピック"
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "API キー (キー)",
"newLabel": "新しいAPIキーキー"
@@ -1543,7 +1547,15 @@
"width": "幅",
"height": "高さ"
},
"placeholder": "あなたのノートを書き始めましょう"
"placeholder": "あなたのノートを書き始めましょう",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "カレンダー",
"description": "カレンダービューで、特定の相対的な期間内に、連携機能からのイベントを表示します",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr リリースタイプ",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "システムリソース",
"description": "CPU、メモリ、ディスクなどのシステムハードウェアの使用",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "CPU",
"memory": "MEM",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": "ファイアウォールのインターフェース"
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "너비",
"height": "높이"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "캘린더",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "레이더 릴리스 유형",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Plotis",
"height": "Aukštis"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalendorius",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "\"Radarr\" išleidimo tipas",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Platums",
"height": "Augstums"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalendārs",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr laiduma tips",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Breedte",
"height": "Hoogte"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalender",
"description": "Gebeurtenissen van je integraties weergeven in een kalenderweergave binnen een bepaalde relatieve tijdsperiode",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr uitgavetype",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Bredde",
"height": "Høyde"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalender",
"description": "Vis hendelser fra integrasjonene dine i en kalendervisning innenfor en bestemt relativ tidsperiode",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr utgivelsestype",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "Temat",
"newLabel": "Nowy temat"
},
"url": {
"label": "Adres URL",
"newLabel": "Nowy adres URL"
},
"opnsenseApiKey": {
"label": "Klucz API",
"newLabel": "Nowy klucz API"
@@ -954,16 +958,16 @@
"newLabel": "Nowy klucz API (Secret)"
},
"githubAppId": {
"label": "",
"newLabel": ""
"label": "Identyfikator aplikacji",
"newLabel": "Nowy identyfikator aplikacji"
},
"githubInstallationId": {
"label": "",
"newLabel": ""
"label": "Identyfikator instalacji",
"newLabel": "Nowy identyfikator instalacji"
},
"privateKey": {
"label": "",
"newLabel": ""
"label": "Klucz prywatny",
"newLabel": "Nowy klucz prywatny"
}
}
},
@@ -1543,7 +1547,15 @@
"width": "Szerokość",
"height": "Wysokość"
},
"placeholder": "Zacznij pisać swoje notatki"
"placeholder": "Zacznij pisać swoje notatki",
"dismiss": {
"title": "Odrzucić zmiany?",
"message": "Masz niezapisane zmiany w notatniku. Czy na pewno chcesz je odrzucić?",
"action": {
"discard": "Odrzuć zmiany",
"keepEditing": "Kontynuuj edycję"
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalendarz",
"description": "Wyświetlaj zdarzenia z integracji w widoku kalendarza w określonym okresie czasowym",
"duration": {
"allDay": "Cały dzień"
},
"option": {
"releaseType": {
"label": "Rodzaj premiery w Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "Zasoby systemowe",
"description": "Wykorzystanie CPU, pamięci, dysku i innych zasobów sprzętowych system",
"option": {},
"option": {
"hasShadow": {
"label": "Włącz cieniowanie wykresu"
},
"visibleCharts": {
"label": "Widoczne wykresy",
"description": "Wybierz wykresy, które chcesz, aby były widoczne.",
"option": {
"cpu": "Procesor",
"memory": "Pamięć",
"network": "Sieć"
}
},
"labelDisplayMode": {
"label": "Tryb wyświetlania etykiet",
"option": {
"textWithIcon": "Pokaż tekst z ikoną",
"text": "Pokaż tylko tekst",
"icon": "Pokaż tylko ikonę",
"hidden": "Ukryj etykietę"
}
}
},
"card": {
"cpu": "Procesor",
"memory": "Pamięć",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": "Interfejsy firewalla"
},
"weather": {
"label": "Pogoda"
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Largura",
"height": "Altura"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Calendário",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Tipo de libertação de Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Lățime",
"height": "Înălțime"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Tip de evenimente ale Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Ширина",
"height": "Высота"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Календарь",
"description": "Отображает события из ваших интеграций в календаре в определённом временном периоде",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Тип релиза Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Šírka",
"height": "Výška"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalendár",
"description": "Zobrazte udalosti z vašich integrácií v zobrazení kalendára za určité relatívne časové obdobie",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Typ Radarr releasu",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Širina",
"height": "Višina"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Koledar",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Tip sprostitve Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Bredd",
"height": "Höjd"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Kalender",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr - händelse att visa i kalendern",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "Konu",
"newLabel": "Yeni konu"
},
"url": {
"label": "Url",
"newLabel": "Yeni url"
},
"opnsenseApiKey": {
"label": "API Anahtarı (Anahtar)",
"newLabel": "Yeni API Anahtarı (Anahtar)"
@@ -1543,7 +1547,15 @@
"width": "Genişlik",
"height": "Yükseklik"
},
"placeholder": "Not almaya başlayın"
"placeholder": "Not almaya başlayın",
"dismiss": {
"title": "Değişikliklerden vazgeçilsin mi?",
"message": "Defterinizde kaydedilmemiş değişiklikleriniz var. Bunları silmek istediğinizden emin misiniz?",
"action": {
"discard": "Değişiklileri at",
"keepEditing": "Düzenlemeyi sürdür"
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Takvim",
"description": "Entegrasyonlarınızdaki etkinlikleri belirli bir göreli zaman dilimi içinde bir takvim görünümünde görüntüleyin",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr yayın türü",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "Sistem kaynakları",
"description": "Sisteminizin CPU, Bellek, Disk ve diğer donanım kullanımları",
"option": {},
"option": {
"hasShadow": {
"label": "Grafik gölgelendirmesini etkinleştir"
},
"visibleCharts": {
"label": "Görünür grafikler",
"description": "Görünür olmasını istediğiniz grafikleri seçin.",
"option": {
"cpu": "İşlemci",
"memory": "Bellek",
"network": "Ağ"
}
},
"labelDisplayMode": {
"label": "Etiket görüntüleme modu",
"option": {
"textWithIcon": "Simge ile metni göster",
"text": "Yalnızca metni göster",
"icon": "Yalnızca simge göster",
"hidden": "Etiketi gizle"
}
}
},
"card": {
"cpu": "İşlemci",
"memory": "BELLEK",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": "Güvenlik Duvarı Arayüzleri"
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Ширина",
"height": "Висота"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Календар",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr - тип релізів",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": "Chủ đề mới"
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "Chiều rộng",
"height": "Chiều cao"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "Lịch",
"description": "",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Loại phát hành Radarr",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"label": ""
}
},
"interval": {

View File

@@ -945,6 +945,10 @@
"label": "",
"newLabel": ""
},
"url": {
"label": "",
"newLabel": ""
},
"opnsenseApiKey": {
"label": "",
"newLabel": ""
@@ -1543,7 +1547,15 @@
"width": "寬度",
"height": "高度"
},
"placeholder": ""
"placeholder": "",
"dismiss": {
"title": "",
"message": "",
"action": {
"discard": "",
"keepEditing": ""
}
}
},
"iframe": {
"name": "iFrame",
@@ -1695,6 +1707,9 @@
"calendar": {
"name": "日曆",
"description": "在特定的相對時間範圍內,將來自您的集成事件以日曆視圖顯示",
"duration": {
"allDay": ""
},
"option": {
"releaseType": {
"label": "Radarr 發行類型",
@@ -2490,7 +2505,29 @@
"systemResources": {
"name": "",
"description": "",
"option": {},
"option": {
"hasShadow": {
"label": ""
},
"visibleCharts": {
"label": "",
"description": "",
"option": {
"cpu": "",
"memory": "",
"network": ""
}
},
"labelDisplayMode": {
"label": "",
"option": {
"textWithIcon": "",
"text": "",
"icon": "",
"hidden": ""
}
}
},
"card": {
"cpu": "",
"memory": "",
@@ -3281,6 +3318,9 @@
},
"firewallInterfaces": {
"label": ""
},
"weather": {
"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.3.1",
"@mantine/dates": "^8.3.1",
"@mantine/hooks": "^8.3.1",
"@mantine/core": "^8.3.2",
"@mantine/dates": "^8.3.2",
"@mantine/hooks": "^8.3.2",
"@tabler/icons-react": "^3.35.0",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.5.3",
"next": "15.5.4",
"react": "19.1.1",
"react-dom": "19.1.1",
"svgson": "^5.3.1"

View File

@@ -14,3 +14,4 @@ export { IntegrationAvatar } from "./integration-avatar";
export { BetaBadge } from "./beta-badge";
export { MaskedImage } from "./masked-image";
export { MaskedOrNormalImage } from "./masked-or-normal-image";
export { LanguageIcon } from "./language-icon";

View File

@@ -0,0 +1,11 @@
import { Image } from "@mantine/core";
import type { LanguageIconDefinition } from "@homarr/translation";
export const LanguageIcon = ({ icon }: { icon: LanguageIconDefinition }) => {
if (icon.type === "flag") {
return <span className={`fi fi-${icon.flag}`} style={{ borderRadius: 4 }}></span>;
}
return <Image src={icon.url} style={{ width: "1.3333em", height: "1.3333em" }} fit="contain" alt="Language icon" />;
};

View File

@@ -1,3 +1,4 @@
import z from "zod";
import { zfd } from "zod-form-data";
import { createCustomErrorParams } from "./form/i18n";
@@ -5,30 +6,34 @@ import { createCustomErrorParams } from "./form/i18n";
export const supportedMediaUploadFormats = ["image/png", "image/jpeg", "image/webp", "image/gif", "image/svg+xml"];
export const mediaUploadSchema = zfd.formData({
file: zfd.file().check((context) => {
if (!supportedMediaUploadFormats.includes(context.value.type)) {
context.issues.push({
code: "custom",
params: createCustomErrorParams({
key: "invalidFileType",
params: { expected: `one of ${supportedMediaUploadFormats.join(", ")}` },
}),
input: context.value.type,
});
return;
}
files: zfd.repeatable(
z.array(
zfd.file().check((context) => {
if (!supportedMediaUploadFormats.includes(context.value.type)) {
context.issues.push({
code: "custom",
params: createCustomErrorParams({
key: "invalidFileType",
params: { expected: `one of ${supportedMediaUploadFormats.join(", ")}` },
}),
input: context.value.type,
});
return;
}
if (context.value.size > 1024 * 1024 * 32) {
// Don't forget to update the limit in nginx.conf (client_max_body_size)
context.issues.push({
code: "custom",
params: createCustomErrorParams({
key: "fileTooLarge",
params: { maxSize: "32 MB" },
}),
input: context.value.size,
});
return;
}
}),
if (context.value.size > 1024 * 1024 * 32) {
// Don't forget to update the limit in nginx.conf (client_max_body_size)
context.issues.push({
code: "custom",
params: createCustomErrorParams({
key: "fileTooLarge",
params: { maxSize: "32 MB" },
}),
input: context.value.size,
});
return;
}
}),
),
),
});

View File

@@ -48,31 +48,31 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/charts": "^8.3.1",
"@mantine/core": "^8.3.1",
"@mantine/hooks": "^8.3.1",
"@mantine/charts": "^8.3.2",
"@mantine/core": "^8.3.2",
"@mantine/hooks": "^8.3.2",
"@tabler/icons-react": "^3.35.0",
"@tiptap/extension-color": "2.26.1",
"@tiptap/extension-highlight": "2.26.1",
"@tiptap/extension-image": "2.26.1",
"@tiptap/extension-link": "^2.26.1",
"@tiptap/extension-placeholder": "^2.26.1",
"@tiptap/extension-table": "2.26.1",
"@tiptap/extension-table-cell": "2.26.1",
"@tiptap/extension-table-header": "2.26.1",
"@tiptap/extension-table-row": "2.26.1",
"@tiptap/extension-task-item": "2.26.1",
"@tiptap/extension-task-list": "2.26.1",
"@tiptap/extension-text-align": "2.26.1",
"@tiptap/extension-text-style": "2.26.1",
"@tiptap/extension-underline": "2.26.1",
"@tiptap/react": "^2.26.1",
"@tiptap/extension-color": "2.26.2",
"@tiptap/extension-highlight": "2.26.2",
"@tiptap/extension-image": "2.26.2",
"@tiptap/extension-link": "^2.26.2",
"@tiptap/extension-placeholder": "^2.26.2",
"@tiptap/extension-table": "2.26.2",
"@tiptap/extension-table-cell": "2.26.2",
"@tiptap/extension-table-header": "2.26.2",
"@tiptap/extension-table-row": "2.26.2",
"@tiptap/extension-task-item": "2.26.2",
"@tiptap/extension-task-list": "2.26.2",
"@tiptap/extension-text-align": "2.26.2",
"@tiptap/extension-text-style": "2.26.2",
"@tiptap/extension-underline": "2.26.2",
"@tiptap/react": "^2.26.2",
"@tiptap/starter-kit": "^2.26.1",
"clsx": "^2.1.1",
"dayjs": "^1.11.18",
"mantine-form-zod-resolver": "^1.3.0",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.5.3",
"next": "15.5.4",
"react": "19.1.1",
"react-dom": "19.1.1",
"react-markdown": "^10.1.0",

View File

@@ -1,13 +1,14 @@
"use client";
import type { ReactNode } from "react";
import { useMemo } from "react";
import { Avatar, Flex, Group, Stack, Text, Title } from "@mantine/core";
import { Fragment, useMemo } from "react";
import { Avatar, Divider, Flex, Group, Stack, Text, Title } from "@mantine/core";
import { IconDeviceTv, IconHeadphones, IconMovie, IconVideo } from "@tabler/icons-react";
import type { MRT_ColumnDef } from "mantine-react-table";
import { MantineReactTable } from "mantine-react-table";
import { clientApi } from "@homarr/api/client";
import { objectEntries } from "@homarr/common";
import { getIconUrl, integrationDefs } from "@homarr/definitions";
import type { StreamSession } from "@homarr/integrations";
import { createModal, useModalAction } from "@homarr/modals";
@@ -123,7 +124,7 @@ export default function MediaServerWidget({
[currentStreams],
);
const { openModal } = useModalAction(itemInfoModal);
const { openModal } = useModalAction(ItemInfoModal);
const table = useTranslatedMantineReactTable({
columns,
data: flatSessions,
@@ -219,10 +220,16 @@ export default function MediaServerWidget({
);
}
const itemInfoModal = createModal<{ item: StreamSession }>(({ innerProps }) => {
const ItemInfoModal = createModal<{ item: StreamSession }>(({ innerProps }) => {
const t = useScopedI18n("widget.mediaServer.items");
const Icon = innerProps.item.currentlyPlaying ? mediaTypeIconMap[innerProps.item.currentlyPlaying.type] : null;
const metadata = useMemo(() => {
return innerProps.item.currentlyPlaying?.metadata
? constructMetadata(innerProps.item.currentlyPlaying.metadata)
: null;
}, [innerProps.item.currentlyPlaying?.metadata]);
return (
<Stack align="center">
<Flex direction="column" gap="xs" align="center">
@@ -255,6 +262,32 @@ const itemInfoModal = createModal<{ item: StreamSession }>(({ innerProps }) => {
/>
<NormalizedLine itemKey={t("name")} value={<Text>{innerProps.item.sessionName}</Text>} />
<NormalizedLine itemKey={t("id")} value={<Text>{innerProps.item.sessionId}</Text>} />
{metadata ? (
<Stack w="100%" gap={0}>
<Divider label={t("metadata.title")} labelPosition="center" mt="lg" mb="sm" />
<Group align="flex-start">
{objectEntries(metadata).map(([key, value], index) => (
<Fragment key={key}>
{index !== 0 && <Divider key={index} orientation="vertical" />}
<Stack gap={4}>
<Text fw="bold">{t(`metadata.${key}.title`)}</Text>
{Object.entries(value)
.filter(([_, value]) => Boolean(value))
.map(([innerKey, value]) => (
<Group justify="space-between" w="100%" key={innerKey} wrap="nowrap">
<Text>{t(`metadata.${key}.${innerKey}` as never)}</Text>
<Text>{value}</Text>
</Group>
))}
</Stack>
</Fragment>
))}
</Group>
</Stack>
) : null}
</Stack>
);
}).withOptions({
@@ -280,3 +313,23 @@ const mediaTypeIconMap = {
video: IconVideo,
audio: IconHeadphones,
} satisfies Record<Exclude<StreamSession["currentlyPlaying"], null>["type"], TablerIcon>;
const constructMetadata = (metadata: Exclude<Exclude<StreamSession["currentlyPlaying"], null>["metadata"], null>) => ({
video: {
resolution: metadata.video.resolution
? `${metadata.video.resolution.width}x${metadata.video.resolution.height}`
: null,
frameRate: metadata.video.frameRate,
},
audio: {
channelCount: metadata.audio.channelCount,
codec: metadata.audio.codec,
},
transcoding: {
container: metadata.transcoding.container,
resolution: metadata.transcoding.resolution
? `${metadata.transcoding.resolution.width}x${metadata.transcoding.resolution.height}`
: null,
target: `${metadata.transcoding.target.videoCodec} ${metadata.transcoding.target.audioCodec}`.trim(),
},
});

View File

@@ -30,18 +30,23 @@ export default function MediaTranscodingWidget({
}: WidgetComponentProps<"mediaTranscoding">) {
const [queuePage, setQueuePage] = useState(1);
const queuePageSize = 10;
const [transcodingData] = clientApi.widget.mediaTranscoding.getDataAsync.useSuspenseQuery(
{
integrationId: integrationIds[0] ?? "",
pageSize: queuePageSize,
page: queuePage,
const input = {
integrationId: integrationIds[0] ?? "",
pageSize: queuePageSize,
page: queuePage,
};
const [transcodingData] = clientApi.widget.mediaTranscoding.getDataAsync.useSuspenseQuery(input, {
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
});
const utils = clientApi.useUtils();
clientApi.widget.mediaTranscoding.subscribeData.useSubscription(input, {
onData(data) {
utils.widget.mediaTranscoding.getDataAsync.setData(input, data);
},
{
refetchOnMount: false,
refetchOnWindowFocus: false,
refetchOnReconnect: false,
},
);
});
const [view, setView] = useState<View>(options.defaultView);
const totalQueuePages = Math.ceil((transcodingData.data.queue.totalCount || 1) / queuePageSize);

View File

@@ -72,6 +72,7 @@ import "./notebook.css";
import { useSession } from "@homarr/auth/client";
import { constructBoardPermissions } from "@homarr/auth/shared";
import { useRequiredBoard } from "@homarr/boards/context";
import { hotkeys } from "@homarr/definitions";
import { useConfirmModal } from "@homarr/modals";
const iconProps = {
@@ -266,7 +267,7 @@ export function Notebook({ options, setOptions, isEditMode, boardId, itemId }: W
p={0}
mt={0}
h="100%"
onKeyDown={isEditing ? getHotkeyHandler([["mod+s", handleEditToggle]]) : undefined}
onKeyDown={isEditing ? getHotkeyHandler([[hotkeys.saveNotebook, handleEditToggle]]) : undefined}
editor={editor}
styles={(theme) => ({
root: {

1390
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -17,14 +17,14 @@
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@next/eslint-plugin-next": "15.5.3",
"@next/eslint-plugin-next": "15.5.4",
"eslint-config-prettier": "^10.1.8",
"eslint-config-turbo": "^2.5.6",
"eslint-config-turbo": "^2.5.8",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"typescript-eslint": "^8.44.0"
"typescript-eslint": "^8.44.1"
},
"devDependencies": {
"@homarr/prettier-config": "workspace:^0.1.0",

View File

@@ -7,7 +7,7 @@ runs:
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v5
with:
node-version: 22.19.0
node-version: 22.20.0
cache: "pnpm"
- shell: bash