mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-11 07:55:52 +01:00
♻️ Add translations for board customize page
This commit is contained in:
5
public/locales/en/boards/common.json
Normal file
5
public/locales/en/boards/common.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"header": {
|
||||
"customize": "Customize board"
|
||||
}
|
||||
}
|
||||
26
public/locales/en/boards/customize.json
Normal file
26
public/locales/en/boards/customize.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"metaTitle": "Customize {{name}} Board",
|
||||
"pageTitle": "Customization for {{name}} Board",
|
||||
"backToBoard": "Back to board",
|
||||
"settings": {
|
||||
"appearance": {
|
||||
"primaryColor": "Primary color",
|
||||
"secondaryColor": "Secondary color"
|
||||
}
|
||||
},
|
||||
"save": "Save changes",
|
||||
"notifications": {
|
||||
"pending": {
|
||||
"title": "Saving customization",
|
||||
"message": "Please wait while we save your customization"
|
||||
},
|
||||
"success": {
|
||||
"title": "Customization saved",
|
||||
"message": "Your customization has been saved successfully"
|
||||
},
|
||||
"error": {
|
||||
"title": "Error",
|
||||
"message": "Unable to save changes"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"label": "App Width"
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"colors": "Colors",
|
||||
"suffix": "{{color}} color"
|
||||
}
|
||||
@@ -23,8 +23,5 @@
|
||||
"description": "Further, customize your dashboard using CSS, only recommended for experienced users",
|
||||
"placeholder": "Custom CSS will be applied last",
|
||||
"applying": "Applying CSS..."
|
||||
},
|
||||
"buttons": {
|
||||
"submit": "Submit"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"label": "Switch to {{scheme}} mode"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"label": "Switch to {{theme}} mode"
|
||||
}
|
||||
@@ -18,11 +18,7 @@ import Editor from 'react-simple-code-editor';
|
||||
import { useBoardCustomizationFormContext } from '../form';
|
||||
|
||||
export const AppearanceCustomization = () => {
|
||||
const { t } = useTranslation([
|
||||
'settings/customization/page-appearance',
|
||||
'settings/customization/color-selector',
|
||||
]);
|
||||
const theme = useMantineTheme();
|
||||
const { t } = useTranslation('settings/customization/page-appearance');
|
||||
const form = useBoardCustomizationFormContext();
|
||||
|
||||
return (
|
||||
@@ -45,7 +41,7 @@ type ColorSelectorProps = {
|
||||
type: 'primaryColor' | 'secondaryColor';
|
||||
};
|
||||
const ColorSelector = ({ type }: ColorSelectorProps) => {
|
||||
const { t } = useTranslation('settings/customization/color-selector');
|
||||
const { t } = useTranslation('boards/customize');
|
||||
const theme = useMantineTheme();
|
||||
const form = useBoardCustomizationFormContext();
|
||||
|
||||
@@ -55,7 +51,7 @@ const ColorSelector = ({ type }: ColorSelectorProps) => {
|
||||
}));
|
||||
|
||||
return (
|
||||
<Input.Wrapper label={type}>
|
||||
<Input.Wrapper label={t(`settings.appearance.${type}`)}>
|
||||
<Group>
|
||||
{colors.map(({ color, swatch }) => (
|
||||
<ColorSwatch
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Button, Checkbox, Grid, Stack } from '@mantine/core';
|
||||
import { IconDeviceFloppy } from '@tabler/icons-react';
|
||||
import { Checkbox, Grid, Stack } from '@mantine/core';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
import { useBoardCustomizationFormContext } from '../form';
|
||||
|
||||
@@ -15,12 +15,12 @@ import { Trans, useTranslation } from 'next-i18next';
|
||||
import Link from 'next/link';
|
||||
import { useEditModeStore } from '~/components/Dashboard/Views/useEditModeStore';
|
||||
import { useNamedWrapperColumnCount } from '~/components/Dashboard/Wrappers/gridstack/store';
|
||||
import { BoardHeadOverride } from '~/components/layout/Meta/BoardHeadOverride';
|
||||
import { HeaderActionButton } from '~/components/layout/header/ActionButton';
|
||||
import { useConfigContext } from '~/config/provider';
|
||||
import { env } from '~/env';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
import { HeaderActionButton } from '~/components/layout/header/ActionButton';
|
||||
import { BoardHeadOverride } from '~/components/layout/Meta/BoardHeadOverride';
|
||||
import { MainLayout } from './MainLayout';
|
||||
|
||||
type BoardLayoutProps = {
|
||||
@@ -68,10 +68,10 @@ const DockerButton = () => {
|
||||
|
||||
const CustomizeBoardButton = () => {
|
||||
const { name } = useConfigContext();
|
||||
console.log('name', name);
|
||||
const { t } = useTranslation('boards/common');
|
||||
|
||||
return (
|
||||
<Tooltip label="Customize board">
|
||||
<Tooltip label={t('header.customize')}>
|
||||
<HeaderActionButton component={Link} href={`/board/${name}/customize`}>
|
||||
<IconSettings size={20} stroke={1.5} />
|
||||
</HeaderActionButton>
|
||||
@@ -158,7 +158,7 @@ const ToggleEditModeButton = () => {
|
||||
if (enabled) {
|
||||
return (
|
||||
<Button.Group>
|
||||
<Tooltip label={t('button.disabled')}>
|
||||
<Tooltip label={t('button.enabled')}>
|
||||
<HeaderActionButton onClick={save}>
|
||||
<IconEditCircleOff size={20} stroke={1.5} />
|
||||
</HeaderActionButton>
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useInitConfig } from '~/config/init';
|
||||
import { configExists } from '~/tools/config/configExists';
|
||||
import { getFrontendConfig } from '~/tools/config/getFrontendConfig';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { dashboardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { ConfigType } from '~/types/config';
|
||||
|
||||
export default function BoardPage({
|
||||
@@ -52,7 +52,7 @@ export const getServerSideProps: GetServerSideProps<BoardGetServerSideProps> = a
|
||||
}
|
||||
|
||||
const config = await getFrontendConfig(routeParams.data.slug);
|
||||
const translations = await getServerSideTranslations(dashboardNamespaces, locale, req, res);
|
||||
const translations = await getServerSideTranslations(boardNamespaces, locale, req, res);
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from '@tabler/icons-react';
|
||||
import { GetServerSideProps } from 'next';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import Head from 'next/head';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import { ReactNode } from 'react';
|
||||
@@ -28,7 +29,8 @@ import { MainLayout } from '~/components/layout/Templates/MainLayout';
|
||||
import { createTrpcServersideHelpers } from '~/server/api/helper';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { dashboardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { firstUpperCase } from '~/tools/shared/strings';
|
||||
import { api } from '~/utils/api';
|
||||
import { useI18nZodResolver } from '~/utils/i18n-zod-resolver';
|
||||
import { boardCustomizationSchema } from '~/validations/dashboards';
|
||||
@@ -41,6 +43,7 @@ export default function CustomizationPage() {
|
||||
const { data: config } = api.config.byName.useQuery({ name: query.slug });
|
||||
const { mutateAsync: saveCusomization, isLoading } = api.config.saveCusomization.useMutation();
|
||||
const { i18nZodResolver } = useI18nZodResolver();
|
||||
const { t } = useTranslation('boards/customize');
|
||||
const form = useBoardCustomizationForm({
|
||||
initialValues: {
|
||||
layout: {
|
||||
@@ -75,8 +78,8 @@ export default function CustomizationPage() {
|
||||
if (isLoading) return;
|
||||
showNotification({
|
||||
id: notificationId,
|
||||
title: 'Saving customization',
|
||||
message: 'Please wait while we save your customization',
|
||||
title: t('notifications.pending.title'),
|
||||
message: t('notifications.pending.message'),
|
||||
loading: true,
|
||||
});
|
||||
await saveCusomization(
|
||||
@@ -91,8 +94,8 @@ export default function CustomizationPage() {
|
||||
onSuccess() {
|
||||
updateNotification({
|
||||
id: notificationId,
|
||||
title: 'Customization saved',
|
||||
message: 'Your customization has been saved',
|
||||
title: t('notifications.success.title'),
|
||||
message: t('notifications.success.message'),
|
||||
color: 'green',
|
||||
icon: <IconCheck />,
|
||||
});
|
||||
@@ -100,8 +103,8 @@ export default function CustomizationPage() {
|
||||
onError() {
|
||||
updateNotification({
|
||||
id: notificationId,
|
||||
title: 'Error',
|
||||
message: 'Unable to save customization',
|
||||
title: t('notifications.error.title'),
|
||||
message: t('notifications.error.message'),
|
||||
color: 'red',
|
||||
icon: <IconX />,
|
||||
});
|
||||
@@ -110,20 +113,31 @@ export default function CustomizationPage() {
|
||||
);
|
||||
};
|
||||
|
||||
const metaTitle = `${t('metaTitle', {
|
||||
name: firstUpperCase(query.slug),
|
||||
})} • Homarr`;
|
||||
|
||||
return (
|
||||
<MainLayout>
|
||||
<Head>
|
||||
<title>{metaTitle}</title>
|
||||
</Head>
|
||||
<Container>
|
||||
<Paper p="xl" py="sm" mih="100%" withBorder>
|
||||
<Stack>
|
||||
<Group position="apart">
|
||||
<Title order={2}>Customization for {query.slug} Board</Title>
|
||||
<Title order={2}>
|
||||
{t('pageTitle', {
|
||||
name: firstUpperCase(query.slug),
|
||||
})}
|
||||
</Title>
|
||||
<Button
|
||||
component={Link}
|
||||
href={`/board/${query.slug}`}
|
||||
variant="light"
|
||||
leftIcon={<IconArrowLeft size={16} />}
|
||||
>
|
||||
Back to Board
|
||||
{t('backToBoard')}
|
||||
</Button>
|
||||
</Group>
|
||||
<BoardCustomizationFormProvider form={form}>
|
||||
@@ -146,7 +160,7 @@ export default function CustomizationPage() {
|
||||
<AppearanceCustomization />
|
||||
</Stack>
|
||||
<Button type="submit" loading={isLoading}>
|
||||
Save changes
|
||||
{t('save')}
|
||||
</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
@@ -200,7 +214,20 @@ export const getServerSideProps: GetServerSideProps = async ({ req, res, locale,
|
||||
|
||||
helpers.config.byName.prefetch({ name: routeParams.data.slug });
|
||||
|
||||
const translations = await getServerSideTranslations(dashboardNamespaces, locale, req, res);
|
||||
const translations = await getServerSideTranslations(
|
||||
[
|
||||
'boards/customize',
|
||||
'settings/common',
|
||||
'settings/customization/general',
|
||||
'settings/customization/page-appearance',
|
||||
'settings/customization/shade-selector',
|
||||
'settings/customization/opacity-selector',
|
||||
'settings/customization/gridstack',
|
||||
],
|
||||
locale,
|
||||
req,
|
||||
res
|
||||
);
|
||||
|
||||
return {
|
||||
props: {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { getServerAuthSession } from '~/server/auth';
|
||||
import { prisma } from '~/server/db';
|
||||
import { getFrontendConfig } from '~/tools/config/getFrontendConfig';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { dashboardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { ConfigType } from '~/types/config';
|
||||
|
||||
export default function BoardPage({
|
||||
@@ -36,7 +36,7 @@ export const getServerSideProps: GetServerSideProps<BoardGetServerSideProps> = a
|
||||
});
|
||||
|
||||
const translations = await getServerSideTranslations(
|
||||
dashboardNamespaces,
|
||||
boardNamespaces,
|
||||
ctx.locale,
|
||||
ctx.req,
|
||||
ctx.res
|
||||
|
||||
@@ -8,7 +8,7 @@ import ContainerActionBar from '~/modules/Docker/ContainerActionBar';
|
||||
import DockerTable from '~/modules/Docker/DockerTable';
|
||||
import { getServerAuthSession } from '~/server/auth';
|
||||
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
|
||||
import { dashboardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { boardNamespaces } from '~/tools/server/translation-namespaces';
|
||||
import { api } from '~/utils/api';
|
||||
|
||||
export default function DockerPage() {
|
||||
@@ -42,7 +42,7 @@ export const getServerSideProps: GetServerSideProps = async ({ locale, req, res
|
||||
};
|
||||
}
|
||||
|
||||
const translations = await getServerSideTranslations(dashboardNamespaces, locale, req, res);
|
||||
const translations = await getServerSideTranslations(boardNamespaces, locale, req, res);
|
||||
return {
|
||||
props: {
|
||||
...translations,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const dashboardNamespaces = [
|
||||
export const boardNamespaces = [
|
||||
'common',
|
||||
'zod',
|
||||
'layout/element-selector/selector',
|
||||
@@ -9,18 +9,10 @@ export const dashboardNamespaces = [
|
||||
'layout/header/actions/toggle-edit-mode',
|
||||
'layout/mobile/drawer',
|
||||
'settings/common',
|
||||
'settings/general/theme-selector',
|
||||
'settings/general/config-changer',
|
||||
'settings/general/internationalization',
|
||||
'settings/general/search-engine',
|
||||
'settings/general/widget-positions',
|
||||
'settings/customization/general',
|
||||
'settings/customization/color-selector',
|
||||
'settings/customization/page-appearance',
|
||||
'settings/customization/shade-selector',
|
||||
'settings/customization/app-width',
|
||||
'settings/customization/opacity-selector',
|
||||
'settings/customization/gridstack',
|
||||
'modules/common',
|
||||
'modules/date',
|
||||
'modules/calendar',
|
||||
@@ -46,6 +38,7 @@ export const dashboardNamespaces = [
|
||||
'widgets/error-boundary',
|
||||
'widgets/draggable-list',
|
||||
'widgets/location',
|
||||
'boards/common',
|
||||
];
|
||||
|
||||
export const manageNamespaces = ['user/preferences', 'zod'];
|
||||
|
||||
Reference in New Issue
Block a user