mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-12 16:35:49 +01:00
✨ i18n translation for modules
This commit is contained in:
1
src/modules/ModuleTypes.d.ts
vendored
1
src/modules/ModuleTypes.d.ts
vendored
@@ -11,6 +11,7 @@ export interface IModule {
|
||||
icon: TablerIcon;
|
||||
component: React.ComponentType;
|
||||
options?: Option;
|
||||
translationNamespace: string;
|
||||
}
|
||||
|
||||
interface Option {
|
||||
|
||||
@@ -25,17 +25,17 @@ import { serviceItem } from '../../tools/types';
|
||||
import { useColorTheme } from '../../tools/color';
|
||||
|
||||
export const CalendarModule: IModule = {
|
||||
title: 'Calendar',
|
||||
description:
|
||||
'A calendar module for displaying upcoming releases. It interacts with the Sonarr and Radarr API.',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: CalendarIcon,
|
||||
component: CalendarComponent,
|
||||
options: {
|
||||
sundaystart: {
|
||||
name: 'Start the week on Sunday',
|
||||
name: 'descriptor.settings.sundayStart.label',
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/calendar-module',
|
||||
};
|
||||
|
||||
export default function CalendarComponent(props: any) {
|
||||
|
||||
@@ -9,33 +9,40 @@ import { IModule } from '../ModuleTypes';
|
||||
|
||||
const asModule = <T extends IModule>(t: T) => t;
|
||||
export const DashdotModule = asModule({
|
||||
title: 'Dash.',
|
||||
description: 'A module for displaying the graphs of your running Dash. instance.',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: CalendarIcon,
|
||||
component: DashdotComponent,
|
||||
options: {
|
||||
cpuMultiView: {
|
||||
name: 'CPU Multi-Core View',
|
||||
name: 'descriptor.settings.cpuMultiView.label',
|
||||
value: false,
|
||||
},
|
||||
storageMultiView: {
|
||||
name: 'Storage Multi-Drive View',
|
||||
name: 'descriptor.settings.storageMultiView.label',
|
||||
value: false,
|
||||
},
|
||||
useCompactView: {
|
||||
name: 'Use Compact View',
|
||||
name: 'descriptor.settings.useCompactView.label',
|
||||
value: false,
|
||||
},
|
||||
graphs: {
|
||||
name: 'Graphs',
|
||||
name: 'descriptor.settings.graphs.label',
|
||||
value: ['CPU', 'RAM', 'Storage', 'Network'],
|
||||
options: ['CPU', 'RAM', 'Storage', 'Network', 'GPU'],
|
||||
options: [
|
||||
'descriptor.settings.graphs.options.cpu',
|
||||
'descriptor.settings.graphs.options.ram',
|
||||
'descriptor.settings.graphs.options.storage',
|
||||
'descriptor.settings.graphs.options.network',
|
||||
'descriptor.settings.graphs.options.GPU',
|
||||
],
|
||||
},
|
||||
url: {
|
||||
name: 'Dash. URL',
|
||||
name: 'descriptor.settings.url.label',
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/dashdot-module',
|
||||
});
|
||||
|
||||
const useStyles = createStyles((theme, _params) => ({
|
||||
|
||||
@@ -7,16 +7,17 @@ import { IModule } from '../ModuleTypes';
|
||||
import { useSetSafeInterval } from '../../tools/hooks/useSetSafeInterval';
|
||||
|
||||
export const DateModule: IModule = {
|
||||
title: 'Date',
|
||||
description: 'Show the current time and date in a card',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: Clock,
|
||||
component: DateComponent,
|
||||
options: {
|
||||
full: {
|
||||
name: 'Display full time (24-hour)',
|
||||
name: 'descriptor.settings.display24HourFormat.label',
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/date-module',
|
||||
};
|
||||
|
||||
export default function DateComponent(props: any) {
|
||||
|
||||
@@ -12,10 +12,11 @@ import { useConfig } from '../../tools/state';
|
||||
import { IModule } from '../ModuleTypes';
|
||||
|
||||
export const DockerModule: IModule = {
|
||||
title: 'Docker',
|
||||
description: 'Allows you to easily manage your torrents',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: IconBrandDocker,
|
||||
component: DockerMenuButton,
|
||||
translationNamespace: 'modules/docker-module',
|
||||
};
|
||||
|
||||
export default function DockerMenuButton(props: any) {
|
||||
|
||||
@@ -15,24 +15,25 @@ import axios from 'axios';
|
||||
import { NormalizedTorrent } from '@ctrl/shared-torrent';
|
||||
import { useViewportSize } from '@mantine/hooks';
|
||||
import { showNotification } from '@mantine/notifications';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { IModule } from '../ModuleTypes';
|
||||
import { useConfig } from '../../tools/state';
|
||||
import { AddItemShelfButton } from '../../components/AppShelf/AddAppShelfItem';
|
||||
import { useSetSafeInterval } from '../../tools/hooks/useSetSafeInterval';
|
||||
import { humanFileSize } from '../../tools/humanFileSize';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
export const DownloadsModule: IModule = {
|
||||
title: 'Torrent',
|
||||
description: 'Show the current download speed of supported services',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: Download,
|
||||
component: DownloadComponent,
|
||||
options: {
|
||||
hidecomplete: {
|
||||
name: 'Hide completed torrents',
|
||||
name: 'descriptor.settings.hideComplete',
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/downloads-module',
|
||||
};
|
||||
|
||||
export default function DownloadComponent() {
|
||||
|
||||
@@ -15,10 +15,11 @@ import { IModule } from '../ModuleTypes';
|
||||
import { useSetSafeInterval } from '../../tools/hooks/useSetSafeInterval';
|
||||
|
||||
export const TotalDownloadsModule: IModule = {
|
||||
title: 'Download Speed',
|
||||
description: 'Show the current download speed of supported services',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: Download,
|
||||
component: TotalDownloadsComponent,
|
||||
translationNamespace: 'modules/total-downloads-module',
|
||||
};
|
||||
|
||||
interface torrentHistory {
|
||||
|
||||
@@ -11,12 +11,15 @@ import {
|
||||
} from '@mantine/core';
|
||||
import { IconAdjustments } from '@tabler/icons';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useState } from 'react';
|
||||
import { useConfig } from '../tools/state';
|
||||
import { IModule } from './ModuleTypes';
|
||||
|
||||
function getItems(module: IModule) {
|
||||
const { config, setConfig } = useConfig();
|
||||
const { t } = useTranslation(module.translationNamespace);
|
||||
|
||||
const items: JSX.Element[] = [];
|
||||
if (module.options) {
|
||||
const keys = Object.keys(module.options);
|
||||
@@ -130,7 +133,7 @@ function getItems(module: IModule) {
|
||||
},
|
||||
});
|
||||
}}
|
||||
label={values[index].name}
|
||||
label={t(values[index].name)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -148,6 +151,7 @@ export function ModuleWrapper(props: any) {
|
||||
const isShown = enabledModules[module.title]?.enabled ?? false;
|
||||
//TODO: fix the hover problem
|
||||
const [hovering, setHovering] = useState(false);
|
||||
const { t } = useTranslation('modules');
|
||||
|
||||
if (!isShown) {
|
||||
return null;
|
||||
@@ -186,6 +190,7 @@ export function ModuleWrapper(props: any) {
|
||||
export function ModuleMenu(props: any) {
|
||||
const { module, styles, hovered } = props;
|
||||
const items: JSX.Element[] = getItems(module);
|
||||
const { t } = useTranslation('modules/common');
|
||||
return (
|
||||
<>
|
||||
{module.options && (
|
||||
@@ -217,7 +222,7 @@ export function ModuleMenu(props: any) {
|
||||
</motion.div>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
<Menu.Label>Settings</Menu.Label>
|
||||
<Menu.Label>{t('settings.label')}</Menu.Label>
|
||||
{items.map((item) => (
|
||||
<Menu.Item key={item.key}>{item}</Menu.Item>
|
||||
))}
|
||||
|
||||
@@ -3,10 +3,11 @@ import { OverseerrMediaDisplay } from '../common';
|
||||
import { IModule } from '../ModuleTypes';
|
||||
|
||||
export const OverseerrModule: IModule = {
|
||||
title: 'Overseerr',
|
||||
description: 'Allows you to search and add media from Overseerr/Jellyseerr',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: IconEyeglass,
|
||||
component: OverseerrMediaDisplay,
|
||||
translationNamespace: 'modules/overseerr-module',
|
||||
};
|
||||
|
||||
export interface OverseerSearchProps {
|
||||
|
||||
@@ -3,15 +3,16 @@ import axios, { AxiosResponse } from 'axios';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { IconPlug as Plug } from '@tabler/icons';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useConfig } from '../../tools/state';
|
||||
import { IModule } from '../ModuleTypes';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
export const PingModule: IModule = {
|
||||
title: 'Ping Services',
|
||||
description: 'Pings your services and shows their status as an indicator',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: Plug,
|
||||
component: PingComponent,
|
||||
translationNamespace: 'modules/ping-module',
|
||||
};
|
||||
|
||||
export default function PingComponent(props: any) {
|
||||
|
||||
@@ -27,10 +27,11 @@ const useStyles = createStyles((theme) => ({
|
||||
}));
|
||||
|
||||
export const SearchModule: IModule = {
|
||||
title: 'Search Bar',
|
||||
description: 'Search bar to search the web, youtube, torrents or overseerr',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: Search,
|
||||
component: SearchBar,
|
||||
translationNamespace: 'modules/search-module',
|
||||
};
|
||||
|
||||
export default function SearchBar(props: any) {
|
||||
|
||||
@@ -19,20 +19,21 @@ import { IModule } from '../ModuleTypes';
|
||||
import { WeatherResponse } from './WeatherInterface';
|
||||
|
||||
export const WeatherModule: IModule = {
|
||||
title: 'Weather',
|
||||
description: 'Look up the current weather in your location',
|
||||
title: 'descriptor.name',
|
||||
description: 'descriptor.description',
|
||||
icon: Sun,
|
||||
component: WeatherComponent,
|
||||
options: {
|
||||
freedomunit: {
|
||||
name: 'Display in Fahrenheit',
|
||||
name: 'descriptor.settings.displayInFahrenheit.label',
|
||||
value: false,
|
||||
},
|
||||
location: {
|
||||
name: 'Current location',
|
||||
name: 'descriptor.settings.location.label',
|
||||
value: 'Paris',
|
||||
},
|
||||
},
|
||||
translationNamespace: 'modules/weather-module',
|
||||
};
|
||||
|
||||
// 0 Clear sky
|
||||
|
||||
Reference in New Issue
Block a user