diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 94d16f4ac..8075fe5a4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -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 diff --git a/.github/workflows/crowdin-schedule-download.yml b/.github/workflows/crowdin-schedule-download.yml index c2f12042a..c4fead5ad 100644 --- a/.github/workflows/crowdin-schedule-download.yml +++ b/.github/workflows/crowdin-schedule-download.yml @@ -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: diff --git a/.github/workflows/deployment-docker-image.yml b/.github/workflows/deployment-docker-image.yml index 1223b4db1..4d980912a 100644 --- a/.github/workflows/deployment-docker-image.yml +++ b/.github/workflows/deployment-docker-image.yml @@ -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' diff --git a/.nvmrc b/.nvmrc index e2228113d..442c7587a 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.19.0 +22.20.0 diff --git a/Dockerfile b/Dockerfile index 7265878d0..7d183cb9c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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 diff --git a/apps/nextjs/package.json b/apps/nextjs/package.json index 1a965fb54..8e41a34ef 100644 --- a/apps/nextjs/package.json +++ b/apps/nextjs/package.json @@ -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", diff --git a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx index 883fce49a..1d7f8aed8 100644 --- a/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx +++ b/apps/nextjs/src/app/[locale]/boards/(content)/_header-actions.tsx @@ -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 ( diff --git a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_background.tsx b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_background.tsx index 71a0450da..7b105fe9c 100644 --- a/apps/nextjs/src/app/[locale]/boards/[name]/settings/_background.tsx +++ b/apps/nextjs/src/app/[locale]/boards/[name]/settings/_background.tsx @@ -120,11 +120,14 @@ export const BackgroundSettingsContent = ({ board }: Props) => { /> {session?.user.permissions.includes("media-upload") && ( + onSuccess={(medias) => { + const first = medias.at(0); + if (!first) return; + startTransition(() => { - form.setFieldValue("backgroundImageUrl", url); - }) - } + form.setFieldValue("backgroundImageUrl", first.url); + }); + }} > {({ onClick, loading }) => ( diff --git a/apps/nextjs/src/app/[locale]/layout.tsx b/apps/nextjs/src/app/[locale]/layout.tsx index afb773f72..3ee6daf89 100644 --- a/apps/nextjs/src/app/[locale]/layout.tsx +++ b/apps/nextjs/src/app/[locale]/layout.tsx @@ -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) => , ]); + const { locale } = await props.params; + return ( // Instead of ColorSchemScript we use data-mantine-color-scheme to prevent flickering + diff --git a/apps/nextjs/src/app/[locale]/manage/about/page.tsx b/apps/nextjs/src/app/[locale]/manage/about/page.tsx index ece275534..8e336449d 100644 --- a/apps/nextjs/src/app/[locale]/manage/about/page.tsx +++ b/apps/nextjs/src/app/[locale]/manage/about/page.tsx @@ -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() { + + }> + + {t("accordion.hotkeys.title")} + + {t("accordion.hotkeys.subtitle")} + + + + + + + + {t("accordion.hotkeys.field.shortcut")} + {t("accordion.hotkeys.field.action")} + + + + {objectEntries(hotkeys).map(([key, shortcut]) => ( + + + + {shortcut + .split("+") + .map((key) => capitalize(key.trim())) + .join(" + ")} + + + {t(`accordion.hotkeys.action.${key}`)} + + ))} + +
+ + + {t("accordion.hotkeys.note")} + +
+
); diff --git a/apps/nextjs/src/app/[locale]/manage/medias/_actions/upload-media.tsx b/apps/nextjs/src/app/[locale]/manage/medias/_actions/upload-media.tsx index ced023c56..377c2edf6 100644 --- a/apps/nextjs/src/app/[locale]/manage/medias/_actions/upload-media.tsx +++ b/apps/nextjs/src/app/[locale]/manage/medias/_actions/upload-media.tsx @@ -14,7 +14,7 @@ export const UploadMediaButton = () => { }; return ( - + {({ onClick, loading }) => (