feat: add support for all languages from old homarr (#1394)

* feat: add support for all languages from old homarr

* fix: add mantine-react-table translations, remove arabic language

* refactor: change translations to json for better crowdin support

* fix: issues with loading dayjs and mantine-react-table translations

* chore: add additional translations with variables

* fix: format and deepsource issues

* fix: test failing because of missing coverage exclusions

* fix: format issues

* fix: format issue
This commit is contained in:
Meier Lukas
2024-11-03 00:11:27 +01:00
committed by GitHub
parent b294bf68cf
commit 0ff7c8903b
49 changed files with 29852 additions and 2843 deletions

View File

@@ -0,0 +1,12 @@
"use client";
import type { PropsWithChildren } from "react";
import { useSuspenseDayJsLocalization } from "@homarr/translation/dayjs";
export const DayJsLoader = ({ children }: PropsWithChildren) => {
// Load the dayjs localization for the current locale with suspense
useSuspenseDayJsLocalization();
return children;
};

View File

@@ -16,7 +16,6 @@ export const CustomMantineProvider = ({
defaultColorScheme,
}: PropsWithChildren<{ defaultColorScheme: ColorScheme }>) => {
const manager = useColorSchemeManager();
return (
<DirectionProvider>
<MantineProvider

View File

@@ -13,12 +13,13 @@ import { env } from "@homarr/auth/env.mjs";
import { auth } from "@homarr/auth/next";
import { ModalProvider } from "@homarr/modals";
import { Notifications } from "@homarr/notifications";
import { isLocaleSupported } from "@homarr/translation";
import { getI18nMessages, getScopedI18n } from "@homarr/translation/server";
import { isLocaleRTL, isLocaleSupported } from "@homarr/translation";
import { getI18nMessages } from "@homarr/translation/server";
import { Analytics } from "~/components/layout/analytics";
import { SearchEngineOptimization } from "~/components/layout/search-engine-optimization";
import { getCurrentColorSchemeAsync } from "~/theme/color-scheme";
import { DayJsLoader } from "./_client-providers/dayjs-loader";
import { JotaiProvider } from "./_client-providers/jotai";
import { CustomMantineProvider } from "./_client-providers/mantine";
import { AuthProvider } from "./_client-providers/session";
@@ -68,8 +69,7 @@ export default async function Layout(props: { children: React.ReactNode; params:
const session = await auth();
const colorScheme = await getCurrentColorSchemeAsync();
const tCommon = await getScopedI18n("common");
const direction = tCommon("direction");
const direction = isLocaleRTL(props.params.locale) ? "rtl" : "ltr";
const i18nMessages = await getI18nMessages();
const StackedProvider = composeWrappers([
@@ -78,6 +78,7 @@ export default async function Layout(props: { children: React.ReactNode; params:
},
(innerProps) => <JotaiProvider {...innerProps} />,
(innerProps) => <TRPCReactProvider {...innerProps} />,
(innerProps) => <DayJsLoader {...innerProps} />,
(innerProps) => <NextIntlClientProvider {...innerProps} messages={i18nMessages} />,
(innerProps) => <CustomMantineProvider {...innerProps} defaultColorScheme={colorScheme} />,
(innerProps) => <ModalProvider {...innerProps} />,

View File

@@ -1,7 +1,6 @@
"use client";
import { useState } from "react";
import { useParams } from "next/navigation";
import { ActionIcon, Avatar, Button, Card, Collapse, Group, Kbd, Stack, Text } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { IconEye, IconEyeOff } from "@tabler/icons-react";
@@ -23,7 +22,6 @@ interface SecretCardProps {
}
export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => {
const params = useParams<{ locale: string }>();
const t = useI18n();
const { isPublic } = integrationSecretKindObject[secret.kind];
const [publicSecretDisplayOpened, { toggle: togglePublicSecretDisplay }] = useDisclosure(false);
@@ -45,7 +43,7 @@ export const SecretCard = ({ secret, children, onCancel }: SecretCardProps) => {
<Group>
<Text c="gray.6" size="sm">
{t("integration.secrets.lastUpdated", {
date: dayjs().locale(params.locale).to(dayjs(secret.updatedAt)),
date: dayjs().to(dayjs(secret.updatedAt)),
})}
</Text>
{isPublic ? (

View File

@@ -1,7 +1,7 @@
"use client";
import React from "react";
import { Combobox, Group, InputBase, Loader, Text, useCombobox } from "@mantine/core";
import { Combobox, Group, InputBase, Loader, ScrollArea, Text, useCombobox } from "@mantine/core";
import { IconCheck } from "@tabler/icons-react";
import type { SupportedLanguage } from "@homarr/translation";
@@ -54,13 +54,15 @@ export const LanguageCombobox = ({ label, value, onChange, isPending }: Language
</InputBase>
</Combobox.Target>
<Combobox.Dropdown>
<Combobox.Options>
{supportedLanguages.map((languageKey) => (
<Combobox.Option value={languageKey} key={languageKey}>
<OptionItem currentLocale={value} localeKey={languageKey} showCheck />
</Combobox.Option>
))}
</Combobox.Options>
<ScrollArea h={300}>
<Combobox.Options>
{supportedLanguages.map((languageKey) => (
<Combobox.Option value={languageKey} key={languageKey}>
<OptionItem currentLocale={value} localeKey={languageKey} showCheck />
</Combobox.Option>
))}
</Combobox.Options>
</ScrollArea>
</Combobox.Dropdown>
</Combobox>
);