Skip to content

Commit 425c9ae

Browse files
feat: add language setting (#520)
1 parent 75cd907 commit 425c9ae

File tree

8 files changed

+67
-16
lines changed

8 files changed

+67
-16
lines changed

src/containers/UserSettings/Setting.tsx

+9-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export interface SettingProps {
1818
helpPopoverContent?: ReactNode;
1919
options?: {value: string; content: string}[];
2020
defaultValue?: unknown;
21+
onValueUpdate?: VoidFunction;
2122
}
2223

2324
export const Setting = ({
@@ -27,9 +28,15 @@ export const Setting = ({
2728
helpPopoverContent,
2829
options,
2930
defaultValue,
31+
onValueUpdate,
3032
}: SettingProps) => {
3133
const [settingValue, setValue] = useSetting(settingKey, defaultValue);
3234

35+
const onUpdate = (value: unknown) => {
36+
setValue(value);
37+
onValueUpdate?.();
38+
};
39+
3340
const renderTitleComponent = (value: ReactNode) => {
3441
if (helpPopoverContent) {
3542
return (
@@ -48,7 +55,7 @@ export const Setting = ({
4855
const getSettingsElement = (elementType: SettingsElementType) => {
4956
switch (elementType) {
5057
case 'switch': {
51-
return <Switch checked={Boolean(settingValue)} onUpdate={setValue} />;
58+
return <Switch checked={Boolean(settingValue)} onUpdate={onUpdate} />;
5259
}
5360

5461
case 'radio': {
@@ -57,7 +64,7 @@ export const Setting = ({
5764
}
5865

5966
return (
60-
<RadioButton value={String(settingValue)} onUpdate={setValue}>
67+
<RadioButton value={String(settingValue)} onUpdate={onUpdate}>
6168
{options.map(({value, content}) => {
6269
return (
6370
<RadioButton.Option value={value} key={value}>

src/containers/UserSettings/i18n/en.json

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"settings.theme.option-light": "Light",
1111
"settings.theme.option-system": "System",
1212

13+
"settings.language.title": "Interface language",
14+
"settings.language.option-russian": "Russian",
15+
"settings.language.option-english": "English",
16+
1317
"settings.invertedDisks.title": "Inverted disks space indicators",
1418

1519
"settings.useNodesEndpoint.title": "Break the Nodes tab in Diagnostics",

src/containers/UserSettings/i18n/ru.json

+4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"settings.theme.option-light": "Светлая",
1111
"settings.theme.option-system": "Системная",
1212

13+
"settings.language.title": "Язык интерфейса",
14+
"settings.language.option-russian": "Русский",
15+
"settings.language.option-english": "English",
16+
1317
"settings.invertedDisks.title": "Инвертированные индикаторы места на дисках",
1418

1519
"settings.useNodesEndpoint.title": "Сломать вкладку Nodes в диагностике",

src/containers/UserSettings/settings.ts

+25
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import flaskIcon from '../../assets/icons/flask.svg';
66
import {
77
ENABLE_ADDITIONAL_QUERY_MODES,
88
INVERTED_DISKS_KEY,
9+
LANGUAGE_KEY,
910
THEME_KEY,
1011
USE_BACKEND_PARAMS_FOR_TABLES_KEY,
1112
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,
1213
} from '../../utils/constants';
14+
import {Lang, defaultLang} from '../../utils/i18n';
1315

1416
import type {SettingProps} from './Setting';
1517
import i18n from './i18n';
@@ -50,6 +52,29 @@ export const themeSetting: SettingProps = {
5052
type: 'radio',
5153
options: themeOptions,
5254
};
55+
56+
const languageOptions = [
57+
{
58+
value: Lang.Ru,
59+
content: i18n('settings.language.option-russian'),
60+
},
61+
{
62+
value: Lang.En,
63+
content: i18n('settings.language.option-english'),
64+
},
65+
];
66+
67+
export const languageSetting: SettingProps = {
68+
settingKey: LANGUAGE_KEY,
69+
title: i18n('settings.language.title'),
70+
type: 'radio',
71+
options: languageOptions,
72+
defaultValue: defaultLang,
73+
onValueUpdate: () => {
74+
window.location.reload();
75+
},
76+
};
77+
5378
export const invertedDisksSetting: SettingProps = {
5479
settingKey: INVERTED_DISKS_KEY,
5580
title: i18n('settings.invertedDisks.title'),

src/store/reducers/settings/settings.ts

+4-10
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ import {
1414
CLUSTER_INFO_HIDDEN_KEY,
1515
LAST_USED_QUERY_ACTION_KEY,
1616
USE_BACKEND_PARAMS_FOR_TABLES_KEY,
17+
LANGUAGE_KEY,
1718
} from '../../../utils/constants';
1819
import '../../../services/api';
19-
import {getValueFromLS, parseJson} from '../../../utils/utils';
20+
import {parseJson} from '../../../utils/utils';
2021
import {QUERY_ACTIONS, QUERY_MODES} from '../../../utils/query';
22+
import {readSavedSettingsValue, systemSettings, userSettings} from '../../../utils/settings';
2123

2224
import {TENANT_PAGES_IDS} from '../tenant/constants';
2325

@@ -38,20 +40,12 @@ export const ProblemFilterValues = {
3840
PROBLEMS: 'With problems',
3941
} as const;
4042

41-
const userSettings = window.userSettings || {};
42-
const systemSettings = window.systemSettings || {};
43-
44-
export function readSavedSettingsValue(key: string, defaultValue?: string) {
45-
const savedValue = window.web_version ? userSettings[key] : getValueFromLS(key);
46-
47-
return savedValue ?? defaultValue;
48-
}
49-
5043
export const initialState = {
5144
problemFilter: ProblemFilterValues.ALL,
5245
userSettings: {
5346
...userSettings,
5447
[THEME_KEY]: readSavedSettingsValue(THEME_KEY, 'system'),
48+
[LANGUAGE_KEY]: readSavedSettingsValue(LANGUAGE_KEY),
5549
[INVERTED_DISKS_KEY]: readSavedSettingsValue(INVERTED_DISKS_KEY, 'false'),
5650
[USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY]: readSavedSettingsValue(
5751
USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY,

src/utils/constants.ts

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export const TENANT_DEFAULT_TITLE = 'Database';
8484

8585
// ==== Settings ====
8686
export const THEME_KEY = 'theme';
87+
export const LANGUAGE_KEY = 'language';
8788
export const INVERTED_DISKS_KEY = 'invertedDisks';
8889
export const USE_NODES_ENDPOINT_IN_DIAGNOSTICS_KEY = 'useNodesEndpointInDiagnostics';
8990
export const ENABLE_ADDITIONAL_QUERY_MODES = 'enableAdditionalQueryModes';

src/utils/i18n/i18n.ts

+10-4
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ import {I18N} from '@gravity-ui/i18n';
22
import {configure as configureUiKit} from '@gravity-ui/uikit';
33
import {configure as configureYdbUiComponents} from 'ydb-ui-components';
44

5+
import {LANGUAGE_KEY} from '../constants';
6+
import {readSavedSettingsValue} from '../settings';
7+
58
enum Lang {
69
En = 'en',
710
Ru = 'ru',
811
}
912

13+
const defaultLang = Lang.En;
14+
const currentLang = readSavedSettingsValue(LANGUAGE_KEY, defaultLang);
15+
1016
const i18n = new I18N();
1117

12-
i18n.setLang(Lang.En);
13-
configureYdbUiComponents({lang: Lang.En});
14-
configureUiKit({lang: Lang.En});
18+
i18n.setLang(currentLang);
19+
configureYdbUiComponents({lang: currentLang});
20+
configureUiKit({lang: currentLang});
1521

16-
export {i18n, Lang};
22+
export {i18n, Lang, currentLang, defaultLang};

src/utils/settings.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {getValueFromLS} from './utils';
2+
3+
export const userSettings = window.userSettings || {};
4+
export const systemSettings = window.systemSettings || {};
5+
6+
export function readSavedSettingsValue(key: string, defaultValue?: string) {
7+
const savedValue = window.web_version ? userSettings[key] : getValueFromLS(key);
8+
9+
return savedValue ?? defaultValue;
10+
}

0 commit comments

Comments
 (0)