2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-12 18:15:40 +00:00

[React] UI Translation Updates (#6257)

* Move locales definition into separate file

- Cleanup settings.py a bit

* Update docstring

* Expose 'default_locale' to info API endpoint

* Validate settings.LANGUAGE_CODE

* Fix bug in BuildDetail page

* Use selected language when making API queries

* Translate more strings

* Tweak variable name

* Update locale config

* Remove duplicate code

* Remove compiled messages.ts translation files

* Fixes for LanguageContext.tsx

* Update messages.d.ts for sr locale

* Ensure compiled files are served by django runserver

* Amend changes to STATICFILES_DIRS

* Cleanup prerender.py

* Refetch status codes when locale is changed

* Fix log msg

* Clear out old static files
This commit is contained in:
Oliver
2024-01-17 16:29:06 +11:00
committed by GitHub
parent 386aa5952c
commit 7d36049ac9
43 changed files with 129 additions and 91 deletions

View File

@ -5,11 +5,14 @@ import { LoadingOverlay, Text } from '@mantine/core';
import { useEffect, useRef, useState } from 'react';
import { api } from '../App';
import { useServerApiState } from '../states/ApiState';
import { useLocalState } from '../states/LocalState';
// Definitions
export type Locales = keyof typeof languages | 'pseudo-LOCALE';
export const defaultLocale = 'en';
export const languages: Record<string, string> = {
bg: t`Bulgarian`,
cs: t`Czech`,
@ -45,6 +48,11 @@ export const languages: Record<string, string> = {
export function LanguageContext({ children }: { children: JSX.Element }) {
const [language] = useLocalState((state) => [state.language]);
const [server] = useServerApiState((state) => [state.server]);
useEffect(() => {
activateLocale(defaultLocale);
}, []);
const [loadedState, setLoadedState] = useState<
'loading' | 'loaded' | 'error'
@ -57,6 +65,32 @@ export function LanguageContext({ children }: { children: JSX.Element }) {
activateLocale(language)
.then(() => {
if (isMounted.current) setLoadedState('loaded');
/*
* Configure the default Accept-Language header for all requests.
* - Locally selected locale
* - Server default locale
* - en-us (backup)
*/
let locales: (string | undefined)[] = [];
if (language != 'pseudo-LOCALE') {
locales.push(language);
}
if (!!server.default_locale) {
locales.push(server.default_locale);
}
if (locales.indexOf('en-us') < 0) {
locales.push('en-us');
}
// Update default Accept-Language headers
api.defaults.headers.common['Accept-Language'] = locales.join(', ');
// Reload server state (refresh status codes)
useServerApiState.getState().fetchServerApiState();
})
.catch((err) => {
console.error('Failed loading translations', err);
@ -90,7 +124,4 @@ export async function activateLocale(locale: Locales) {
const { messages } = await import(`../locales/${locale}/messages.ts`);
i18n.load(locale, messages);
i18n.activate(locale);
// Set api header
api.defaults.headers.common['Accept-Language'] = locale;
}

View File

@ -16,7 +16,8 @@ export const emptyServerAPI = {
system_health: null,
platform: null,
installer: null,
target: null
target: null,
default_locale: null
};
export interface SiteMarkProps {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
import { Messages } from '@lingui/core';
declare const messages: Messages;
export { messages };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import { Trans } from '@lingui/macro';
import { Trans, t } from '@lingui/macro';
import { Button, Group, Stack, Text, TextInput, Title } from '@mantine/core';
import { useForm } from '@mantine/form';
import { useToggle } from '@mantine/hooks';
@ -37,13 +37,13 @@ export function AccountDetailPanel() {
{editing ? (
<Stack spacing="xs">
<TextInput
label="First name"
placeholder="First name"
label="first name"
placeholder={t`First name`}
{...form.getInputProps('first_name')}
/>
<TextInput
label="Last name"
placeholder="Last name"
placeholder={t`Last name`}
{...form.getInputProps('last_name')}
/>
<Group position="right" mt="md">
@ -55,10 +55,12 @@ export function AccountDetailPanel() {
) : (
<Stack spacing="0">
<Text>
<Trans>First name: {form.values.first_name}</Trans>
<Trans>First name: </Trans>
{form.values.first_name}
</Text>
<Text>
<Trans>Last name: {form.values.last_name}</Trans>
<Trans>Last name: </Trans>
{form.values.last_name}
</Text>
</Stack>
)}

View File

@ -1,5 +1,5 @@
import { t } from '@lingui/macro';
import { Group, LoadingOverlay, Stack, Table } from '@mantine/core';
import { Group, LoadingOverlay, Skeleton, Stack, Table } from '@mantine/core';
import {
IconClipboardCheck,
IconClipboardList,
@ -78,7 +78,7 @@ export default function BuildDetail() {
<tr>
<td>{t`Build Status`}</td>
<td>
{build.status && (
{build?.status && (
<StatusRenderer
status={build.status}
type={ModelType.build}
@ -241,10 +241,14 @@ export default function BuildDetail() {
}, [id, build, user]);
const buildDetail = useMemo(() => {
return StatusRenderer({
status: build.status,
type: ModelType.build
});
return build?.status ? (
StatusRenderer({
status: build.status,
type: ModelType.build
})
) : (
<Skeleton />
);
}, [build, id]);
return (

View File

@ -37,6 +37,7 @@ export interface ServerAPIProps {
platform: null | string;
installer: null | string;
target: null | string;
default_locale: null | string;
}
// Type interface defining a single 'setting' object