chore(release): automatic release v1.42.0

This commit is contained in:
homarr-releases[bot]
2025-10-17 19:14:09 +00:00
committed by GitHub
76 changed files with 1640 additions and 939 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.41.0
- 1.40.0
- 1.39.0
- 1.38.0

View File

@@ -50,12 +50,12 @@
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@homarr/widgets": "workspace:^0.1.0",
"@mantine/colors-generator": "^8.3.3",
"@mantine/core": "^8.3.3",
"@mantine/dropzone": "^8.3.3",
"@mantine/hooks": "^8.3.3",
"@mantine/modals": "^8.3.3",
"@mantine/tiptap": "^8.3.3",
"@mantine/colors-generator": "^8.3.4",
"@mantine/core": "^8.3.4",
"@mantine/dropzone": "^8.3.4",
"@mantine/hooks": "^8.3.4",
"@mantine/modals": "^8.3.4",
"@mantine/tiptap": "^8.3.4",
"@million/lint": "1.0.14",
"@tabler/icons-react": "^3.35.0",
"@tanstack/react-query": "^5.90.2",
@@ -85,19 +85,19 @@
"react-simple-code-editor": "^0.14.1",
"sass": "^1.93.2",
"superjson": "2.2.2",
"swagger-ui-react": "^5.29.3",
"swagger-ui-react": "^5.29.4",
"use-deep-compare-effect": "^1.8.1",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/chroma-js": "3.1.1",
"@types/node": "^22.18.8",
"@types/node": "^22.18.10",
"@types/prismjs": "^1.26.5",
"@types/react": "19.2.0",
"@types/react-dom": "19.2.0",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.1",
"@types/swagger-ui-react": "^5.18.0",
"concurrently": "^9.2.1",
"eslint": "^9.37.0",

View File

@@ -2,6 +2,7 @@ import { Box, Grid, GridCol, Group, Image, Stack, Title } from "@mantine/core";
import { splitToNChunks } from "@homarr/common";
import { integrationDefs } from "@homarr/definitions";
import { getScopedI18n } from "@homarr/translation/server";
import classes from "./hero-banner.module.css";
@@ -12,19 +13,20 @@ const icons = Object.values(integrationDefs)
const countIconGroups = 3;
const animationDurationInSeconds = icons.length;
const arrayInChunks = splitToNChunks(icons, countIconGroups);
const gridSpan = 12 / countIconGroups;
export const HeroBanner = () => {
const gridSpan = 12 / countIconGroups;
export const HeroBanner = async () => {
const t = await getScopedI18n("management.page.home");
return (
<Box className={classes.bannerContainer} p={{ base: "lg", md: "3rem" }} bg="dark.6" pos="relative">
<Stack gap={0}>
<Title fz={{ base: "h4", md: "h2" }} c="dimmed">
Welcome back to your
{t("heroBanner.title")}
</Title>
<Group gap="xs" wrap="nowrap">
<Image src="/logo/logo.png" w={{ base: 32, md: 40 }} h={{ base: 32, md: 40 }} />
<Title fz={{ base: "h3", md: "h1" }}>Homarr Board</Title>
<Title fz={{ base: "h3", md: "h1" }}>{t("heroBanner.subtitle", { app: "Homarr" })}</Title>
</Group>
</Stack>
<Box visibleFrom="md" className={classes.scrollContainer} w={"30%"} top={0} right={0} pos="absolute">

View File

@@ -1,25 +1,16 @@
import type { Metadata } from "next";
import Link from "next/link";
import { Card, Group, SimpleGrid, Space, Stack, Text } from "@mantine/core";
import { IconArrowRight } from "@tabler/icons-react";
import { api } from "@homarr/api/server";
import { auth } from "@homarr/auth/next";
import { isProviderEnabled } from "@homarr/auth/server";
import { getScopedI18n } from "@homarr/translation/server";
import { DynamicBreadcrumb } from "~/components/navigation/dynamic-breadcrumb";
import { createMetaTitle } from "~/metadata";
import { HeroBanner } from "./_components/hero-banner";
interface LinkProps {
title: string;
subtitle: string;
count: number;
href: string;
hidden?: boolean;
}
export async function generateMetadata() {
export async function generateMetadata(): Promise<Metadata> {
const t = await getScopedI18n("management");
return {
@@ -29,78 +20,32 @@ export async function generateMetadata() {
export default async function ManagementPage() {
const statistics = await api.home.getStats();
const session = await auth();
const t = await getScopedI18n("management.page.home");
const links: LinkProps[] = [
{
count: statistics.countBoards,
href: "/manage/boards",
subtitle: t("statisticLabel.boards"),
title: t("statistic.board"),
},
{
count: statistics.countUsers,
href: "/manage/users",
subtitle: t("statisticLabel.authentication"),
title: t("statistic.user"),
hidden: !session?.user.permissions.includes("admin"),
},
{
count: statistics.countInvites,
href: "/manage/users/invites",
subtitle: t("statisticLabel.authentication"),
title: t("statistic.invite"),
hidden: !isProviderEnabled("credentials") || !session?.user.permissions.includes("admin"),
},
{
count: statistics.countIntegrations,
href: "/manage/integrations",
subtitle: t("statisticLabel.resources"),
title: t("statistic.integration"),
},
{
count: statistics.countApps,
href: "/manage/apps",
subtitle: t("statisticLabel.resources"),
title: t("statistic.app"),
hidden: !session?.user,
},
{
count: statistics.countGroups,
href: "/manage/users/groups",
subtitle: t("statisticLabel.authorization"),
title: t("statistic.group"),
hidden: !session?.user.permissions.includes("admin"),
},
];
return (
<>
<DynamicBreadcrumb />
<HeroBanner />
<Space h="md" />
<SimpleGrid cols={{ xs: 1, sm: 2, md: 3 }}>
{links.map(
(link) =>
!link.hidden && (
<Card component={Link} href={link.href} key={link.href} radius="lg">
<Group justify="space-between" wrap="nowrap">
<Group wrap="nowrap">
<Text size="2.4rem" fw="bolder">
{link.count}
</Text>
<Stack gap={0}>
<Text c="red" size="xs">
{link.subtitle}
</Text>
<Text fw="bold">{link.title}</Text>
</Stack>
</Group>
<IconArrowRight />
</Group>
</Card>
),
)}
{statistics.map((statistic) => (
<Card component={Link} href={statistic.path} key={statistic.path} radius="lg">
<Group justify="space-between" wrap="nowrap">
<Group wrap="nowrap">
<Text size="2.4rem" fw="bolder">
{statistic.count}
</Text>
<Stack gap={0}>
<Text c="red" size="xs">
{t(`statisticLabel.${statistic.subtitleKey}`)}
</Text>
<Text fw="bold">{t(`statistic.${statistic.titleKey}`)}</Text>
</Stack>
</Group>
<IconArrowRight />
</Group>
</Card>
))}
</SimpleGrid>
</>
);

View File

@@ -92,38 +92,24 @@ export const UserProfileAvatarForm = ({ user }: UserProfileAvatarForm) => {
});
}, [mutate, user.id, openConfirmModal, tManageAvatar]);
const isCredentialsUser = user.provider === "credentials";
return (
<Box pos="relative">
<Menu
opened={opened}
keepMounted
onChange={isCredentialsUser ? toggle : undefined}
position="bottom-start"
withArrow
>
<Menu opened={opened} keepMounted onChange={toggle} position="bottom-start" withArrow>
<Menu.Target>
<UnstyledButton
component={isCredentialsUser ? undefined : "div"}
style={{ cursor: !isCredentialsUser ? "default" : undefined }}
onClick={isCredentialsUser ? toggle : undefined}
>
<UnstyledButton onClick={toggle}>
<UserAvatar user={user} size={200} />
{isCredentialsUser && (
<Button
component="div"
pos="absolute"
bottom={0}
left={0}
size="compact-md"
fw="normal"
variant="default"
leftSection={<IconPencil size={18} stroke={1.5} />}
>
{t("common.action.edit")}
</Button>
)}
<Button
component="div"
pos="absolute"
bottom={0}
left={0}
size="compact-md"
fw="normal"
variant="default"
leftSection={<IconPencil size={18} stroke={1.5} />}
>
{t("common.action.edit")}
</Button>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>

View File

@@ -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.8",
"@types/node": "^22.18.10",
"dotenv-cli": "^10.0.0",
"esbuild": "^0.25.10",
"eslint": "^9.37.0",

View File

@@ -58,7 +58,7 @@
"vite-tsconfig-paths": "^5.1.4",
"vitest": "^3.2.4"
},
"packageManager": "pnpm@10.18.0",
"packageManager": "pnpm@10.18.2",
"engines": {
"node": ">=22.20.0"
},
@@ -82,7 +82,7 @@
"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.10",
"hono@<4.6.5": ">=4.9.11",
"linkifyjs@<4.3.2": ">=4.3.2",
"nanoid@>=4.0.0 <5.0.9": ">=5.1.6",
"prismjs@<1.30.0": ">=1.30.0",

View File

@@ -40,6 +40,7 @@
"@homarr/redis": "workspace:^0.1.0",
"@homarr/request-handler": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@kubernetes/client-node": "^1.4.0",
"@tanstack/react-query": "^5.90.2",
@@ -52,8 +53,8 @@
"react": "19.2.0",
"react-dom": "19.2.0",
"superjson": "2.2.2",
"trpc-to-openapi": "^3.0.1",
"zod": "^4.1.11"
"trpc-to-openapi": "^3.1.0",
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -1,31 +1,147 @@
import type { AnySQLiteTable } from "drizzle-orm/sqlite-core";
import { isProviderEnabled } from "@homarr/auth/server";
import type { Database } from "@homarr/db";
import { apps, boards, groups, integrations, invites, users } from "@homarr/db/schema";
import { db, eq, inArray, or } from "@homarr/db";
import {
apps,
boards,
boardUserPermissions,
groupMembers,
groups,
integrations,
invites,
medias,
searchEngines,
users,
} from "@homarr/db/schema";
import type { TranslationObject } from "@homarr/translation";
import { createTRPCRouter, publicProcedure } from "../trpc";
interface HomeStatistic {
titleKey: keyof TranslationObject["management"]["page"]["home"]["statistic"];
subtitleKey: keyof TranslationObject["management"]["page"]["home"]["statisticLabel"];
count: number;
path: string;
}
export const homeRouter = createTRPCRouter({
getStats: publicProcedure.query(async ({ ctx }) => {
const isAdmin = ctx.session?.user.permissions.includes("admin") ?? false;
const isCredentialsEnabled = isProviderEnabled("credentials");
return {
countBoards: await getCountForTableAsync(ctx.db, boards, true),
countUsers: await getCountForTableAsync(ctx.db, users, isAdmin),
countGroups: await getCountForTableAsync(ctx.db, groups, true),
countInvites: await getCountForTableAsync(ctx.db, invites, isAdmin),
countIntegrations: await getCountForTableAsync(ctx.db, integrations, isCredentialsEnabled && isAdmin),
countApps: await getCountForTableAsync(ctx.db, apps, true),
};
const statistics: HomeStatistic[] = [];
const boardIds: string[] = [];
if (ctx.session?.user && !ctx.session.user.permissions.includes("board-view-all")) {
const permissionsOfCurrentUserWhenPresent = await ctx.db.query.boardUserPermissions.findMany({
where: eq(boardUserPermissions.userId, ctx.session.user.id),
});
const permissionsOfCurrentUserGroupsWhenPresent = await ctx.db.query.groupMembers.findMany({
where: eq(groupMembers.userId, ctx.session.user.id),
with: {
group: {
with: {
boardPermissions: {},
},
},
},
});
boardIds.push(
...permissionsOfCurrentUserWhenPresent
.map((permission) => permission.boardId)
.concat(
permissionsOfCurrentUserGroupsWhenPresent
.map((groupMember) => groupMember.group.boardPermissions.map((permission) => permission.boardId))
.flat(),
),
);
}
statistics.push({
titleKey: "board",
subtitleKey: "boards",
count: await db.$count(
boards,
ctx.session?.user.permissions.includes("board-view-all")
? undefined
: or(
eq(boards.isPublic, true),
eq(boards.creatorId, ctx.session?.user.id ?? ""),
boardIds.length > 0 ? inArray(boards.id, boardIds) : undefined,
),
),
path: "/manage/boards",
});
if (isAdmin) {
statistics.push({
titleKey: "user",
subtitleKey: "authentication",
count: await db.$count(users),
path: "/manage/users",
});
}
if (isAdmin && isCredentialsEnabled) {
statistics.push({
titleKey: "invite",
subtitleKey: "authentication",
count: await db.$count(invites),
path: "/manage/users/invites",
});
}
if (ctx.session?.user.permissions.includes("integration-create")) {
statistics.push({
titleKey: "integration",
subtitleKey: "resources",
count: await db.$count(integrations),
path: "/manage/integrations",
});
}
if (ctx.session?.user) {
statistics.push({
titleKey: "app",
subtitleKey: "resources",
count: await db.$count(apps),
path: "/manage/apps",
});
}
if (isAdmin) {
statistics.push({
titleKey: "group",
subtitleKey: "authorization",
count: await db.$count(groups),
path: "/manage/users/groups",
});
}
if (ctx.session?.user.permissions.includes("search-engine-create")) {
statistics.push({
titleKey: "searchEngine",
subtitleKey: "resources",
count: await db.$count(searchEngines),
path: "/manage/search-engines",
});
}
if (ctx.session?.user.permissions.includes("media-upload")) {
statistics.push({
titleKey: "media",
subtitleKey: "resources",
count: await db.$count(
medias,
ctx.session.user.permissions.includes("media-view-all")
? undefined
: eq(medias.creatorId, ctx.session.user.id),
),
path: "/manage/medias",
});
}
return statistics;
}),
});
const getCountForTableAsync = async (db: Database, table: AnySQLiteTable, canView: boolean) => {
if (!canView) {
return 0;
}
return await db.$count(table);
};

View File

@@ -114,11 +114,10 @@ export const userRouter = createTRPCRouter({
.input(
z.object({
userId: z.string(),
// Max image size of 256KB, only png and jpeg are allowed
image: z
.string()
.regex(/^data:image\/(png|jpeg|gif|webp);base64,[A-Za-z0-9/+]+=*$/g)
.max(262144)
.max(350000) // approximately 256KB in base64 (256 * 1024 * 4 / 3 + prefixes)
.nullable(),
}),
)
@@ -147,13 +146,6 @@ export const userRouter = createTRPCRouter({
});
}
if (user.provider !== "credentials") {
throw new TRPCError({
code: "FORBIDDEN",
message: "Profile image can not be changed for users with external providers",
});
}
await ctx.db
.update(users)
.set({

View File

@@ -20,6 +20,7 @@ export const createSignInEventHandler = (db: Database): Exclude<NextAuthConfig["
where: eq(users.id, user.id),
columns: {
name: true,
image: true,
colorScheme: true,
},
});
@@ -59,6 +60,15 @@ export const createSignInEventHandler = (db: Database): Exclude<NextAuthConfig["
`Username for user of oidc provider has changed. user=${user.id} old='${dbUser.name}' new='${profileUsername}'`,
);
}
if (
typeof profile.picture === "string" &&
dbUser.image !== profile.picture &&
!dbUser.image?.startsWith("data:")
) {
await db.update(users).set({ image: profile.picture }).where(eq(users.id, user.id));
logger.info(`Profile picture for user of oidc provider has changed. user=${user.id}'`);
}
}
logger.info(`User '${dbUser.name}' logged in at ${dayjs().format()}`);

View File

@@ -23,8 +23,8 @@
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@auth/core": "^0.40.0",
"@auth/drizzle-adapter": "^1.10.0",
"@auth/core": "^0.41.0",
"@auth/drizzle-adapter": "^1.11.0",
"@homarr/certificates": "workspace:^0.1.0",
"@homarr/common": "workspace:^0.1.0",
"@homarr/core": "workspace:^0.1.0",
@@ -39,7 +39,7 @@
"next-auth": "5.0.0-beta.29",
"react": "19.2.0",
"react-dom": "19.2.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -61,6 +61,7 @@ export const OidcProvider = (headers: ReadonlyHeaders | null): OIDCConfig<Profil
id: profile.sub,
name,
email: profile.email,
image: typeof profile.picture === "string" ? profile.picture : null,
provider: "oidc",
};
},

View File

@@ -37,7 +37,7 @@
"react": "19.2.0",
"react-dom": "19.2.0",
"undici": "7.16.0",
"zod": "^4.1.11",
"zod": "^4.1.12",
"zod-validation-error": "^4.0.2"
},
"devDependencies": {

View File

@@ -25,8 +25,8 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@t3-oss/env-nextjs": "^0.13.8",
"ioredis": "5.8.0",
"zod": "^4.1.11"
"ioredis": "5.8.1",
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -35,14 +35,14 @@
"@trpc/tanstack-react-query": "^11.6.0",
"node-cron": "^4.2.1",
"react": "19.2.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",
"@homarr/prettier-config": "workspace:^0.1.0",
"@homarr/tsconfig": "workspace:^0.1.0",
"@types/node-cron": "^3.0.11",
"@types/react": "19.2.0",
"@types/react": "19.2.2",
"eslint": "^9.37.0",
"typescript": "^5.9.3"
}

View File

@@ -43,13 +43,13 @@
},
"prettier": "@homarr/prettier-config",
"dependencies": {
"@auth/core": "^0.40.0",
"@auth/core": "^0.41.0",
"@homarr/common": "workspace:^0.1.0",
"@homarr/core": "workspace:^0.1.0",
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/log": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/core": "^8.3.3",
"@mantine/core": "^8.3.4",
"@paralleldrive/cuid2": "^2.2.2",
"@testcontainers/mysql": "^11.7.1",
"@testcontainers/postgresql": "^11.7.1",
@@ -58,7 +58,7 @@
"drizzle-kit": "^0.31.5",
"drizzle-orm": "^0.44.6",
"drizzle-zod": "^0.8.3",
"mysql2": "3.15.1",
"mysql2": "3.15.2",
"pg": "^8.16.3",
"superjson": "2.2.2"
},

View File

@@ -25,7 +25,7 @@
"dependencies": {
"@homarr/common": "workspace:^0.1.0",
"fast-xml-parser": "^5.3.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -26,9 +26,9 @@
"@homarr/common": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/form": "^8.3.3",
"@mantine/form": "^8.3.4",
"mantine-form-zod-resolver": "^1.3.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -29,9 +29,9 @@
"@homarr/notifications": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.3.3",
"@mantine/core": "^8.3.4",
"react": "19.2.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -26,7 +26,7 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@ctrl/deluge": "^7.4.0",
"@ctrl/qbittorrent": "^9.9.0",
"@ctrl/qbittorrent": "^9.9.1",
"@ctrl/transmission": "^7.4.0",
"@gitbeaker/rest": "^43.5.0",
"@homarr/certificates": "workspace:^0.1.0",
@@ -49,7 +49,7 @@
"tsdav": "^2.1.5",
"undici": "7.16.0",
"xml2js": "^0.6.2",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -1,4 +1,7 @@
import type { Agent } from "https";
import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import type { RequestInit as NodeFetchRequestInit } from "node-fetch";
import * as ical from "node-ical";
import { DAVClient } from "tsdav";
@@ -14,6 +17,9 @@ import type { TestingResult } from "../base/test-connection/test-connection-serv
import type { ICalendarIntegration } from "../interfaces/calendar/calendar-integration";
import type { CalendarEvent } from "../interfaces/calendar/calendar-types";
dayjs.extend(utc);
dayjs.extend(timezone);
@HandleIntegrationErrors([integrationTsdavHttpErrorHandler])
export class NextcloudIntegration extends Integration implements ICalendarIntegration {
protected async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
@@ -41,47 +47,59 @@ export class NextcloudIntegration extends Integration implements ICalendarIntegr
)
).flat();
return calendarEvents.map((event): CalendarEvent => {
// @ts-expect-error the typescript definitions for this package are wrong
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
const icalData = ical.default.parseICS(event.data) as ical.CalendarResponse;
const veventObject = Object.values(icalData).find((data) => data.type === "VEVENT");
return calendarEvents
.map((event) => {
// @ts-expect-error the typescript definitions for this package are wrong
// eslint-disable-next-line @typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
const icalData = ical.default.parseICS(event.data) as ical.CalendarResponse;
const veventObject = Object.values(icalData).find((data) => data.type === "VEVENT");
if (!veventObject) {
throw new Error(`Invalid event data object: ${JSON.stringify(event.data)}. Unable to process the calendar.`);
}
if (!veventObject) {
throw new Error(`Invalid event data object: ${JSON.stringify(event.data)}. Unable to process the calendar.`);
}
logger.debug(`Converting VEVENT event to ${event.etag} from Nextcloud: ${JSON.stringify(veventObject)}`);
logger.debug(`Converting VEVENT event to ${event.etag} from Nextcloud: ${JSON.stringify(veventObject)}`);
const date = veventObject.start;
const eventUrlWithoutHost = new URL(event.url).pathname;
const eventSlug = Buffer.from(eventUrlWithoutHost).toString("base64url");
const eventUrlWithoutHost = new URL(event.url).pathname;
const dateInMillis = veventObject.start.valueOf();
const startDates = veventObject.rrule ? veventObject.rrule.between(start, end) : [veventObject.start];
const url = this.url(
`/apps/calendar/timeGridWeek/now/edit/sidebar/${Buffer.from(eventUrlWithoutHost).toString("base64url")}/${dateInMillis / 1000}`,
);
const durationMs = veventObject.end.getTime() - veventObject.start.getTime();
return {
title: veventObject.summary,
subTitle: null,
description: veventObject.description,
startDate: date,
endDate: veventObject.end,
image: null,
location: veventObject.location || null,
indicatorColor: "#ff8600",
links: [
{
href: url.toString(),
name: "Nextcloud",
logo: "/images/apps/nextcloud.svg",
color: undefined,
isDark: true,
},
],
};
});
return startDates.map((startDate) => {
const timezoneOffsetMinutes = veventObject.rrule?.origOptions.tzid
? dayjs(startDate).tz(veventObject.rrule.origOptions.tzid).utcOffset()
: 0;
const utcStartDate = new Date(startDate.getTime() - timezoneOffsetMinutes * 60 * 1000);
const endDate = new Date(utcStartDate.getTime() + durationMs);
const dateInMillis = utcStartDate.valueOf();
return {
title: veventObject.summary,
subTitle: null,
description: veventObject.description,
startDate: utcStartDate,
endDate,
image: null,
location: veventObject.location || null,
indicatorColor:
"color" in veventObject && typeof veventObject.color === "string" ? veventObject.color : "#ff8600",
links: [
{
href: this.url(
`/apps/calendar/timeGridWeek/now/edit/sidebar/${eventSlug}/${dateInMillis / 1000}`,
).toString(),
name: "Nextcloud",
logo: "/images/apps/nextcloud.svg",
color: undefined,
isDark: true,
},
],
};
});
})
.flat();
}
private async createCalendarClientAsync(agent?: Agent) {

View File

@@ -142,7 +142,10 @@ export class PlexIntegration extends Integration implements IMediaServerIntegrat
rating: item.rating?.toFixed(1),
tags: item.Genre?.map((genre) => genre.tag) ?? [],
href: super
.url(`/web/index.html#!/server/${machineIdentifier}/details?key=${encodeURIComponent(item.key)}`)
.url(
// Url with children on the end results in infinite loading screen, see https://github.com/homarr-labs/homarr/issues/4078
`/web/index.html#!/server/${machineIdentifier}/details?key=${encodeURIComponent(item.key.replace("/children", ""))}`,
)
.toString(),
length: item.duration ? Math.round(item.duration / 1000) : undefined,
};

View File

@@ -27,7 +27,7 @@
"@homarr/core": "workspace:^0.1.0",
"superjson": "2.2.2",
"winston": "3.18.3",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -33,13 +33,13 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.3.3",
"@mantine/core": "^8.3.4",
"@tabler/icons-react": "^3.35.0",
"dayjs": "^1.11.18",
"next": "15.5.4",
"react": "19.2.0",
"react-dom": "19.2.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -24,8 +24,8 @@
"dependencies": {
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.3.3",
"@mantine/hooks": "^8.3.3",
"@mantine/core": "^8.3.4",
"@mantine/hooks": "^8.3.4",
"react": "19.2.0"
},
"devDependencies": {

View File

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

View File

@@ -37,14 +37,14 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.3.3",
"@mantine/hooks": "^8.3.3",
"@mantine/core": "^8.3.4",
"@mantine/hooks": "^8.3.4",
"adm-zip": "0.5.16",
"next": "15.5.4",
"react": "19.2.0",
"react-dom": "19.2.0",
"superjson": "2.2.2",
"zod": "^4.1.11",
"zod": "^4.1.12",
"zod-form-data": "^3.0.1"
},
"devDependencies": {

View File

@@ -23,7 +23,7 @@
"prettier": "@homarr/prettier-config",
"dependencies": {
"@homarr/common": "workspace:^0.1.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

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

View File

@@ -33,7 +33,7 @@
"octokit": "^5.0.3",
"superjson": "2.2.2",
"undici": "7.16.0",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

View File

@@ -47,7 +47,7 @@ async function getContainersWithStatsAsync() {
const instance = dockerInstances.find(({ host }) => host === container.instance)?.instance;
if (!instance) return null;
const stats = await instance.getContainer(container.Id).stats({ stream: false });
const stats = await instance.getContainer(container.Id).stats({ stream: false, "one-shot": true });
return {
id: container.Id,
@@ -60,7 +60,8 @@ async function getContainersWithStatsAsync() {
return icon.name.toLowerCase().includes(extractedImage.toLowerCase());
})?.url ?? null,
cpuUsage: calculateCpuUsage(stats),
memoryUsage: stats.memory_stats.usage,
// memory usage by default includes cache, which should not be shown as it is also not shown with docker stats command
memoryUsage: stats.memory_stats.usage - stats.memory_stats.stats.cache,
image: container.Image,
ports: container.Ports,
};

View File

@@ -26,7 +26,7 @@
"@homarr/api": "workspace:^0.1.0",
"@homarr/db": "workspace:^0.1.0",
"@homarr/server-settings": "workspace:^0.1.0",
"@mantine/dates": "^8.3.3",
"@mantine/dates": "^8.3.4",
"next": "15.5.4",
"react": "19.2.0",
"react-dom": "19.2.0"

View File

@@ -33,9 +33,9 @@
"@homarr/settings": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@mantine/core": "^8.3.3",
"@mantine/hooks": "^8.3.3",
"@mantine/spotlight": "^8.3.3",
"@mantine/core": "^8.3.4",
"@mantine/hooks": "^8.3.4",
"@mantine/spotlight": "^8.3.4",
"@tabler/icons-react": "^3.35.0",
"jotai": "^2.15.0",
"next": "15.5.4",

View File

@@ -33,7 +33,7 @@
"deepmerge": "4.3.1",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.5.4",
"next-intl": "4.3.9",
"next-intl": "4.3.12",
"react": "19.2.0",
"react-dom": "19.2.0"
},

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": ""
},
@@ -2974,13 +2986,19 @@
"invite": "",
"integration": "",
"app": "",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "用户组名称已存在"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "标题"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "边界颜色"
}
@@ -1744,6 +1753,9 @@
"label": "显示当前风速",
"description": "仅在当前天气时"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "天气位置"
},
@@ -2974,13 +2986,19 @@
"invite": "邀请",
"integration": "集成",
"app": "应用",
"group": "群组"
"group": "群组",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "面板",
"resources": "资源",
"authentication": "认证",
"authorization": "认证"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "crwdns2366:0crwdne2366:0"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "crwdns3764:0crwdne3764:0",
"milesPerHour": "crwdns3766:0crwdne3766:0"
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "crwdns3103:0crwdne3103:0"
},
"customCssClasses": {
"label": "crwdns3776:0crwdne3776:0"
},
"borderColor": {
"label": "crwdns2839:0crwdne2839:0"
}
@@ -1744,6 +1753,9 @@
"label": "crwdns2706:0crwdne2706:0",
"description": "crwdns2708:0crwdne2708:0"
},
"useImperialSpeed": {
"label": "crwdns3768:0crwdne3768:0"
},
"location": {
"label": "crwdns1018:0crwdne1018:0"
},
@@ -1762,12 +1774,12 @@
"description": "crwdns1030:0crwdne1030:0"
}
},
"currentWindSpeed": "crwdns2710:0{currentWindSpeed}crwdne2710:0",
"currentWindSpeed": "crwdns3770:0{currentWindSpeed}crwdnd3770:0{unit}crwdne3770:0",
"dailyForecast": {
"sunrise": "crwdns2712:0crwdne2712:0",
"sunset": "crwdns2714:0crwdne2714:0",
"maxWindSpeed": "crwdns2716:0{maxWindSpeed}crwdne2716:0",
"maxWindGusts": "crwdns2718:0{maxWindGusts}crwdne2718:0"
"maxWindSpeed": "crwdns3772:0{maxWindSpeed}crwdnd3772:0{unit}crwdne3772:0",
"maxWindGusts": "crwdns3774:0{maxWindGusts}crwdnd3774:0{unit}crwdne3774:0"
},
"kind": {
"clear": "crwdns1032:0crwdne1032:0",
@@ -2974,13 +2986,19 @@
"invite": "crwdns1620:0crwdne1620:0",
"integration": "crwdns1622:0crwdne1622:0",
"app": "crwdns1624:0crwdne1624:0",
"group": "crwdns1626:0crwdne1626:0"
"group": "crwdns1626:0crwdne1626:0",
"searchEngine": "crwdns3778:0crwdne3778:0",
"media": "crwdns3780:0crwdne3780:0"
},
"statisticLabel": {
"boards": "crwdns1628:0crwdne1628:0",
"resources": "crwdns1630:0crwdne1630:0",
"authentication": "crwdns1632:0crwdne1632:0",
"authorization": "crwdns1634:0crwdne1634:0"
},
"heroBanner": {
"title": "crwdns3782:0crwdne3782:0",
"subtitle": "crwdns3784:0{app}crwdne3784:0"
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Název skupiny je již používán"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Lokalita pro počasí"
},
@@ -2974,13 +2986,19 @@
"invite": "Pozvánky",
"integration": "",
"app": "Aplikace",
"group": "Skupiny"
"group": "Skupiny",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Plochy",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Gruppenavn allerede taget"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Titel"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Kantfarve"
}
@@ -1708,7 +1717,7 @@
"name": "Kalender",
"description": "Vis begivenheder fra dine integrationer i en kalendervisning inden for en vis relativ tidsperiode",
"duration": {
"allDay": ""
"allDay": "Hele dagen"
},
"option": {
"releaseType": {
@@ -1744,6 +1753,9 @@
"label": "Vis aktuel vindhastighed",
"description": "Kun på nuværende vejr"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Vejr lokation"
},
@@ -1982,21 +1994,21 @@
"name": "Navn",
"id": "Id",
"metadata": {
"title": "",
"title": "Statistik for nørder",
"video": {
"title": "",
"resolution": ""
"title": "Video",
"resolution": "Opløsning"
},
"audio": {
"title": "",
"channelCount": "",
"codec": ""
"title": "Lyd",
"channelCount": "Lyd kanaler",
"codec": "Lyd codec"
},
"transcoding": {
"title": "",
"container": "",
"resolution": "",
"target": ""
"title": "Transkoder",
"container": "Container",
"resolution": "Opløsning",
"target": "Mål codec"
}
}
}
@@ -2974,13 +2986,19 @@
"invite": "Invitationer",
"integration": "Integrationer",
"app": "Apps",
"group": "Grupper"
"group": "Grupper",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Tavler",
"resources": "Ressourcer",
"authentication": "Autorisering",
"authorization": "Autorisation"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {
@@ -3338,7 +3356,7 @@
"label": "Firewall Grænseflader"
},
"weather": {
"label": ""
"label": "Vejr"
}
},
"interval": {
@@ -3466,19 +3484,19 @@
"subtitle": "{count} brugt i koden for Homarr"
},
"hotkeys": {
"title": "",
"subtitle": "",
"title": "Genvejstaster",
"subtitle": "Tastaturgenveje til at forbedre din arbejdsgang",
"field": {
"shortcut": "",
"action": ""
"shortcut": "Genvej",
"action": "Handling"
},
"action": {
"toggleBoardEdit": "",
"toggleColorScheme": "",
"saveNotebook": "",
"openSpotlight": ""
"toggleBoardEdit": "Skift tavleredigeringstilstand",
"toggleColorScheme": "Slå lys/mørk tilstand til/fra",
"saveNotebook": "Gem notesbog (kun inde i notesbog widget)",
"openSpotlight": "Åbn søgefunktionen"
},
"note": ""
"note": "Tip: Mod refererer til både Ctrl-tasten og -tasten på macOS"
}
}
}

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Gruppenname bereits vergeben"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Rahmenfarbe"
}
@@ -1744,6 +1753,9 @@
"label": "Aktuelle Windgeschwindigkeit anzeigen",
"description": "Nur bei aktuellem Wetter"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Wetterstandort"
},
@@ -2974,13 +2986,19 @@
"invite": "Einladungen",
"integration": "Integrationen",
"app": "",
"group": "Gruppen"
"group": "Gruppen",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "",
"resources": "Ressourcen",
"authentication": "Authentifizierung",
"authorization": "Autorisierung"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Gruppenname bereits vergeben"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Titel"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Rahmenfarbe"
}
@@ -1744,6 +1753,9 @@
"label": "Aktuelle Windgeschwindigkeit anzeigen",
"description": "Nur bei aktuellem Wetter"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Wetterstandort"
},
@@ -2974,13 +2986,19 @@
"invite": "Einladungen",
"integration": "Integrationen",
"app": "Apps",
"group": "Gruppen"
"group": "Gruppen",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Boards",
"resources": "Ressourcen",
"authentication": "Authentifizierung",
"authorization": "Autorisierung"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Τοποθεσία καιρού"
},
@@ -2974,13 +2986,19 @@
"invite": "Προσκλήσεις",
"integration": "",
"app": "Εφαρμογές",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Πίνακες",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "An existing group already has this name"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Title"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Border colour"
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": ""
},
@@ -2974,13 +2986,19 @@
"invite": "",
"integration": "",
"app": "",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -2986,13 +2986,19 @@
"invite": "Invites",
"integration": "Integrations",
"app": "Apps",
"group": "Groups"
"group": "Groups",
"searchEngine": "Search engines",
"media": "Medias"
},
"statisticLabel": {
"boards": "Boards",
"resources": "Resources",
"authentication": "Authentication",
"authorization": "Authorization"
},
"heroBanner": {
"title": "Welcome back to your",
"subtitle": "{app} Board"
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Nombre del grupo en uso"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "km/h",
"milesPerHour": "mph"
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Título"
},
"customCssClasses": {
"label": "Clases CSS personalizadas"
},
"borderColor": {
"label": "Color del borde"
}
@@ -1744,6 +1753,9 @@
"label": "Mostrar velocidad del viento actual",
"description": "Sólo en el tiempo actual"
},
"useImperialSpeed": {
"label": "Usar mph para la velocidad del viento"
},
"location": {
"label": "Ubicación"
},
@@ -1762,12 +1774,12 @@
"description": "Cómo debería ser la fecha"
}
},
"currentWindSpeed": "{currentWindSpeed} km/h",
"currentWindSpeed": "{currentWindSpeed} {unit}",
"dailyForecast": {
"sunrise": "Amanecer",
"sunset": "Atardecer",
"maxWindSpeed": "Velocidad máxima del viento: {maxWindSpeed} km/h",
"maxWindGusts": "Máximas ráfagas de viento: {maxWindGusts} km/h"
"maxWindSpeed": "Velocidad máxima del viento: {maxWindSpeed} {unit}",
"maxWindGusts": "Máximas ráfagas de viento: {maxWindGusts} {unit}"
},
"kind": {
"clear": "Despejado",
@@ -2225,7 +2237,7 @@
"total": "Total"
},
"users": {
"main": "Mejores usuarios",
"main": "Clasificación de usuarios",
"requests": "Solicitudes"
}
}
@@ -2974,13 +2986,19 @@
"invite": "Invitaciones",
"integration": "Integraciones",
"app": "Aplicaciones",
"group": "Grupos"
"group": "Grupos",
"searchEngine": "Motores de búsqueda",
"media": "Imágenes"
},
"statisticLabel": {
"boards": "Tableros",
"resources": "Recursos",
"authentication": "Autenticación",
"authorization": "Autenticación"
},
"heroBanner": {
"title": "Bienvenido de nuevo a tu",
"subtitle": "Tablero de {app}"
}
},
"board": {
@@ -3044,11 +3062,11 @@
"general": {
"title": "General",
"item": {
"language": "Idioma y región",
"language": "Idioma",
"board": {
"title": "Tablero de inicio",
"title": "Tableros",
"type": {
"general": "General",
"general": "Escritorio",
"mobile": "Móvil"
}
},
@@ -3217,7 +3235,7 @@
"board": {
"title": "Tableros",
"homeBoard": {
"label": "Tablero de inicio global",
"label": "Tablero de escritorio global",
"mobileLabel": "Tablero móvil global",
"description": "Sólo los tableros públicos están disponibles para la selección"
},
@@ -4397,7 +4415,7 @@
"page": {
"list": {
"title": "Certificados de confianza",
"description": "Utilizado por Homarr para solicitar datos de las integraciones.",
"description": "Utilizados por Homarr para solicitar datos de las integraciones.",
"noResults": {
"title": "Aún no hay certificados"
},

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": ""
},
@@ -2974,13 +2986,19 @@
"invite": "",
"integration": "",
"app": "",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Nom de groupe déjà utilisé"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Titre"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Couleur de la bordure"
}
@@ -1744,6 +1753,9 @@
"label": "Afficher la vitesse actuelle du vent",
"description": "Uniquement sur la météo actuelle"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Lieu de la météo"
},
@@ -2974,13 +2986,19 @@
"invite": "Invitations",
"integration": "Intégrations",
"app": "Applications",
"group": "Groupes"
"group": "Groupes",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Tableaux de bord",
"resources": "Ressources",
"authentication": "Authentification",
"authorization": "Autorisation"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "שם הקבוצה כבר תפוס"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "כותרת"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "צבע מסגרת"
}
@@ -1744,6 +1753,9 @@
"label": "הצגת מהירות רוח נוכחית",
"description": "רק במזג אוויר נוכחי"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "מיקום מזג האוויר"
},
@@ -2974,13 +2986,19 @@
"invite": "הזמנות",
"integration": "אינטגרציות",
"app": "אפליקציות",
"group": "קבוצות"
"group": "קבוצות",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "לוחות",
"resources": "מקורות",
"authentication": "אימות",
"authorization": "הרשאה"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Lokacija vremenske prognoze"
},
@@ -2974,13 +2986,19 @@
"invite": "poziva",
"integration": "",
"app": "aplikacije",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Daske",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Időjárás helye"
},
@@ -2974,13 +2986,19 @@
"invite": "Meghívók",
"integration": "Integrációk",
"app": "Alkalmazások",
"group": "Csoportok"
"group": "Csoportok",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Táblák",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Nome gruppo già preso"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Titolo"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Colore del bordo"
}
@@ -1744,6 +1753,9 @@
"label": "Mostra la velocità attuale del vento",
"description": "Solo sul meteo corrente"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Località meteo"
},
@@ -2974,13 +2986,19 @@
"invite": "Inviti",
"integration": "Integrazioni",
"app": "Applicazioni",
"group": "Gruppi"
"group": "Gruppi",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Board",
"resources": "Risorse",
"authentication": "Autenticazione",
"authorization": "Autorizzazione"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "グループ名は、既に使用されています"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "タイトル"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "境界線の色"
}
@@ -1744,6 +1753,9 @@
"label": "現在の風速を表示",
"description": "現在の天気のみ表示"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "天候の場所"
},
@@ -2974,13 +2986,19 @@
"invite": "招待",
"integration": "連携機能",
"app": "アプリ",
"group": "グループ"
"group": "グループ",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "ボード",
"resources": "リソース",
"authentication": "認証",
"authorization": "認可"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "날씨 위치"
},
@@ -2974,13 +2986,19 @@
"invite": "초대",
"integration": "",
"app": "앱",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "보드",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": ""
},
@@ -2974,13 +2986,19 @@
"invite": "Pakvietimai",
"integration": "",
"app": "Programėlės",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Lentos",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Laikapstākļu atrašānās vieta"
},
@@ -2974,13 +2986,19 @@
"invite": "Uzaicinājumi",
"integration": "",
"app": "Lietotnes",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Dēļi",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Groepsnaam al in gebruik"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Titel"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Randkleur"
}
@@ -1744,6 +1753,9 @@
"label": "Toon huidige windsnelheid",
"description": "Alleen op het huidige weer"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Weerlocatie"
},
@@ -2974,13 +2986,19 @@
"invite": "Uitnodigingen",
"integration": "Integraties",
"app": "Apps",
"group": "Groepen"
"group": "Groepen",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Borden",
"resources": "Bronnen",
"authentication": "Authenticatie",
"authorization": "Authorisatie"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Gruppenavn allerede tatt"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Grensefarge"
}
@@ -1744,6 +1753,9 @@
"label": "Vis nåværende vindhastighet",
"description": "Bare på nåværende vær"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Vær plassering"
},
@@ -2974,13 +2986,19 @@
"invite": "Invitasjoner",
"integration": "Integrasjoner",
"app": "Apper",
"group": "Grupper"
"group": "Grupper",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Tavler",
"resources": "Ressurser",
"authentication": "Autentisering",
"authorization": "Autorisasjon"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -389,7 +389,7 @@
}
},
"media": {
"title": "Media",
"title": "Multimedia",
"item": {
"upload": {
"label": "Prześlij media",
@@ -978,7 +978,7 @@
}
},
"media": {
"plural": "Medias",
"plural": "Multimedia",
"search": "Znajdź media",
"field": {
"name": "Nazwa",
@@ -1145,6 +1145,12 @@
"groupNameTaken": "Nazwa użytkownika jest już zajęta"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "km/h",
"milesPerHour": "mph"
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Tytuł"
},
"customCssClasses": {
"label": "Niestandardowe klasy CSS"
},
"borderColor": {
"label": "Kolor obramowania"
}
@@ -1744,6 +1753,9 @@
"label": "Pokaż aktualną prędkość wiatru",
"description": "Tylko dla bieżącej pogody"
},
"useImperialSpeed": {
"label": "Prędkość wiatru w mph"
},
"location": {
"label": "Lokalizacja pogody"
},
@@ -2974,13 +2986,19 @@
"invite": "Zaproszenia",
"integration": "Integracje",
"app": "Aplikacje",
"group": "Grupy"
"group": "Grupy",
"searchEngine": "Wyszukiwarki",
"media": "Multimedia"
},
"statisticLabel": {
"boards": "Tablice",
"resources": "Zasoby",
"authentication": "Uwierzytelnianie",
"authorization": "Autoryzacja"
},
"heroBanner": {
"title": "Witaj z powrotem w swojej",
"subtitle": "{app} tablicy"
}
},
"board": {

View File

@@ -153,7 +153,7 @@
"label": "Usar ícone para pings"
},
"defaultSearchEngine": {
"label": "Mecanismo de busca padrão"
"label": "Mecanismo de pesquisa padrão"
},
"openSearchInNewTab": {
"label": "Abrir resultados da busca em uma nova aba"
@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Localização do tempo"
},
@@ -2974,13 +2986,19 @@
"invite": "Convites",
"integration": "",
"app": "Aplicativos",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Placas",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Locație meteo"
},
@@ -2974,13 +2986,19 @@
"invite": "Invitații",
"integration": "",
"app": "Aplicații",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Planșe",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Имя группы уже занято"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Цвет границы"
}
@@ -1744,6 +1753,9 @@
"label": "Показать текущую скорость ветра",
"description": "Только для текущей погоды"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Местоположение"
},
@@ -2974,13 +2986,19 @@
"invite": "Приглашения",
"integration": "Интеграции",
"app": "Приложения",
"group": "Группы"
"group": "Группы",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Панели",
"resources": "Ресурсы",
"authentication": "Аутентификация",
"authorization": "Авторизация"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Názov skupiny je už obsadený"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Názov"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Farba okraja"
}
@@ -1744,6 +1753,9 @@
"label": "Zobraziť aktuálnu rýchlosť vetra",
"description": "Len za aktuálneho počasia"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Poloha počasia"
},
@@ -2974,13 +2986,19 @@
"invite": "Pozvánky",
"integration": "Integrácie",
"app": "Aplikácie",
"group": "Skupiny"
"group": "Skupiny",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Dosky",
"resources": "Zdroje",
"authentication": "Autentifikácia",
"authorization": "Autorizácia"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Lokacija vremena"
},
@@ -2974,13 +2986,19 @@
"invite": "Vabi",
"integration": "",
"app": "Aplikacije",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Deske",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Plats för väder"
},
@@ -2974,13 +2986,19 @@
"invite": "Inbjudningar",
"integration": "Integrationer",
"app": "Applikationer",
"group": "Grupper"
"group": "Grupper",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Tavlor",
"resources": "Resurser",
"authentication": "Autentisering",
"authorization": "Auktorisering"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Grup adı zaten alınmış"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "Başlık"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "Kenarlık rengi"
}
@@ -1744,6 +1753,9 @@
"label": "Mevcut rüzgar hızını göster",
"description": "Yalnızca mevcut hava durumunda"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Hava durumu konumu"
},
@@ -2974,13 +2986,19 @@
"invite": "Davetler",
"integration": "Entegrasyonlar",
"app": "Uygulamalar",
"group": "Gruplar"
"group": "Gruplar",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Paneller",
"resources": "Kaynaklar",
"authentication": "Kimlik doğrulama",
"authorization": "Yetkilendirme"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "Назва групи вже зайнята"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "Показати поточну швидкість вітру",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Погодна локація"
},
@@ -2974,13 +2986,19 @@
"invite": "Запрошення",
"integration": "Інтеграції",
"app": "Додатки",
"group": "Групи"
"group": "Групи",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Дошки",
"resources": "Ресурси",
"authentication": "Аутентифікація",
"authorization": "Авторизація"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": ""
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": ""
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": ""
}
@@ -1744,6 +1753,9 @@
"label": "",
"description": ""
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "Vị trí thời tiết"
},
@@ -2974,13 +2986,19 @@
"invite": "Mời",
"integration": "",
"app": "Ứng dụng",
"group": ""
"group": "",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "Bảng",
"resources": "",
"authentication": "",
"authorization": ""
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -1145,6 +1145,12 @@
"groupNameTaken": "用戶組名稱已存在"
}
}
},
"unit": {
"speed": {
"kilometersPerHour": "",
"milesPerHour": ""
}
}
},
"section": {
@@ -1157,6 +1163,9 @@
"title": {
"label": "標題"
},
"customCssClasses": {
"label": ""
},
"borderColor": {
"label": "邊框顏色"
}
@@ -1744,6 +1753,9 @@
"label": "顯示當前風速",
"description": "僅限當前天氣"
},
"useImperialSpeed": {
"label": ""
},
"location": {
"label": "天氣位置"
},
@@ -2974,13 +2986,19 @@
"invite": "邀請",
"integration": "集成",
"app": "應用程式",
"group": "群組"
"group": "群組",
"searchEngine": "",
"media": ""
},
"statisticLabel": {
"boards": "面板",
"resources": "資源",
"authentication": "認證",
"authorization": "認證"
},
"heroBanner": {
"title": "",
"subtitle": ""
}
},
"board": {

View File

@@ -30,9 +30,9 @@
"@homarr/log": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/core": "^8.3.3",
"@mantine/dates": "^8.3.3",
"@mantine/hooks": "^8.3.3",
"@mantine/core": "^8.3.4",
"@mantine/dates": "^8.3.4",
"@mantine/hooks": "^8.3.4",
"@tabler/icons-react": "^3.35.0",
"mantine-react-table": "2.0.0-beta.9",
"next": "15.5.4",

View File

@@ -24,7 +24,7 @@
"dependencies": {
"@homarr/definitions": "workspace:^0.1.0",
"@homarr/translation": "workspace:^0.1.0",
"zod": "^4.1.11",
"zod": "^4.1.12",
"zod-form-data": "^3.0.1"
},
"devDependencies": {

View File

@@ -48,26 +48,26 @@
"@homarr/translation": "workspace:^0.1.0",
"@homarr/ui": "workspace:^0.1.0",
"@homarr/validation": "workspace:^0.1.0",
"@mantine/charts": "^8.3.3",
"@mantine/core": "^8.3.3",
"@mantine/hooks": "^8.3.3",
"@mantine/charts": "^8.3.4",
"@mantine/core": "^8.3.4",
"@mantine/hooks": "^8.3.4",
"@tabler/icons-react": "^3.35.0",
"@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",
"@tiptap/extension-color": "2.26.3",
"@tiptap/extension-highlight": "2.26.3",
"@tiptap/extension-image": "2.26.3",
"@tiptap/extension-link": "^2.26.3",
"@tiptap/extension-placeholder": "^2.26.3",
"@tiptap/extension-table": "2.26.3",
"@tiptap/extension-table-cell": "2.26.3",
"@tiptap/extension-table-header": "2.26.3",
"@tiptap/extension-table-row": "2.26.3",
"@tiptap/extension-task-item": "2.26.3",
"@tiptap/extension-task-list": "2.26.3",
"@tiptap/extension-text-align": "2.26.3",
"@tiptap/extension-text-style": "2.26.3",
"@tiptap/extension-underline": "2.26.3",
"@tiptap/react": "^2.26.3",
"@tiptap/starter-kit": "^2.26.3",
"clsx": "^2.1.1",
"dayjs": "^1.11.18",
"mantine-form-zod-resolver": "^1.3.0",
@@ -78,7 +78,7 @@
"react-markdown": "^10.1.0",
"recharts": "^2.15.4",
"video.js": "^8.23.4",
"zod": "^4.1.11"
"zod": "^4.1.12"
},
"devDependencies": {
"@homarr/eslint-config": "workspace:^0.2.0",

1259
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

File diff suppressed because one or more lines are too long

View File

@@ -24,7 +24,7 @@
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^6.1.1",
"typescript-eslint": "^8.45.0"
"typescript-eslint": "^8.46.0"
},
"devDependencies": {
"@homarr/prettier-config": "workspace:^0.1.0",