Skip to content

Commit fccd7be

Browse files
author
sunlinyao
committed
support i18n
1 parent d9e9843 commit fccd7be

28 files changed

+414
-88
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,5 @@ compilation-stats.json
102102
/public/e2e-test/screenShots/theOutput
103103
/public/e2e-tests/screenShots/theOutput/*.png
104104
/public/e2e-tests/videos
105+
yarn.lock
106+
package-lock.json

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@
206206
"@grafana/slate-react": "0.22.9-grafana",
207207
"@torkelo/react-select": "2.4.1",
208208
"@types/react-loadable": "5.5.2",
209+
"@types/webpack-env": "1.14.1",
209210
"angular": "1.6.9",
210211
"angular-bindonce": "0.3.1",
211212
"angular-native-dragdrop": "1.2.2",
@@ -223,6 +224,7 @@
223224
"fast-text-encoding": "^1.0.0",
224225
"file-saver": "1.3.8",
225226
"hoist-non-react-statics": "3.3.0",
227+
"i18next": "19.0.2",
226228
"immutable": "3.8.2",
227229
"is-hotkey": "0.1.4",
228230
"jquery": "3.4.1",
@@ -242,6 +244,7 @@
242244
"react-dom": "16.12.0",
243245
"react-grid-layout": "0.16.6",
244246
"react-highlight-words": "0.11.0",
247+
"react-i18next": "11.2.7",
245248
"react-loadable": "5.5.0",
246249
"react-popper": "1.3.3",
247250
"react-redux": "7.1.1",

pkg/api/dtos/models.go

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ type CurrentUser struct {
3636
IsGrafanaAdmin bool `json:"isGrafanaAdmin"`
3737
GravatarUrl string `json:"gravatarUrl"`
3838
Timezone string `json:"timezone"`
39+
Language string `json:"language"`
3940
Locale string `json:"locale"`
4041
HelpFlags1 m.HelpFlags1 `json:"helpFlags1"`
4142
HasEditPermissionInFolders bool `json:"hasEditPermissionInFolders"`

pkg/api/dtos/prefs.go

+2
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ type Prefs struct {
44
Theme string `json:"theme"`
55
HomeDashboardID int64 `json:"homeDashboardId"`
66
Timezone string `json:"timezone"`
7+
Language string `json:"language"`
78
}
89

910
type UpdatePrefsCmd struct {
1011
Theme string `json:"theme"`
1112
HomeDashboardID int64 `json:"homeDashboardId"`
1213
Timezone string `json:"timezone"`
14+
Language string `json:"language"`
1315
}

pkg/api/index.go

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ func (hs *HTTPServer) setIndexViewData(c *m.ReqContext) (*dtos.IndexViewData, er
6969
IsGrafanaAdmin: c.IsGrafanaAdmin,
7070
LightTheme: prefs.Theme == lightName,
7171
Timezone: prefs.Timezone,
72+
Language: prefs.Language,
7273
Locale: locale,
7374
HelpFlags1: c.HelpFlags1,
7475
HasEditPermissionInFolders: hasEditPermissionInFoldersQuery.Result,

pkg/api/preferences.go

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func getPreferencesFor(orgID, userID, teamID int64) Response {
3535
Theme: prefsQuery.Result.Theme,
3636
HomeDashboardID: prefsQuery.Result.HomeDashboardId,
3737
Timezone: prefsQuery.Result.Timezone,
38+
Language: prefsQuery.Result.Language,
3839
}
3940

4041
return JSON(200, &dto)
@@ -52,6 +53,7 @@ func updatePreferencesFor(orgID, userID, teamId int64, dtoCmd *dtos.UpdatePrefsC
5253
TeamId: teamId,
5354
Theme: dtoCmd.Theme,
5455
Timezone: dtoCmd.Timezone,
56+
Language: dtoCmd.Language,
5557
HomeDashboardId: dtoCmd.HomeDashboardID,
5658
}
5759

pkg/models/preferences.go

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type Preferences struct {
1818
Version int
1919
HomeDashboardId int64
2020
Timezone string
21+
Language string
2122
Theme string
2223
Created time.Time
2324
Updated time.Time
@@ -50,5 +51,6 @@ type SavePreferencesCommand struct {
5051

5152
HomeDashboardId int64 `json:"homeDashboardId"`
5253
Timezone string `json:"timezone"`
54+
Language string `json:"language"`
5355
Theme string `json:"theme"`
5456
}

pkg/services/sqlstore/migrations/preferences_mig.go

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ func addPreferencesMigrations(mg *Migrator) {
1515
{Name: "version", Type: DB_Int, Nullable: false},
1616
{Name: "home_dashboard_id", Type: DB_BigInt, Nullable: false},
1717
{Name: "timezone", Type: DB_NVarchar, Length: 50, Nullable: false},
18+
{Name: "language", Type: DB_NVarchar, Length: 50, Nullable: false},
1819
{Name: "theme", Type: DB_NVarchar, Length: 20, Nullable: false},
1920
{Name: "created", Type: DB_DateTime, Nullable: false},
2021
{Name: "updated", Type: DB_DateTime, Nullable: false},

pkg/services/sqlstore/preferences.go

+6
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func GetPreferencesWithDefaults(query *m.GetPreferencesWithDefaultsQuery) error
4242
res := &m.Preferences{
4343
Theme: setting.DefaultTheme,
4444
Timezone: "browser",
45+
Language: setting.DefaultLanguage,
4546
HomeDashboardId: 0,
4647
}
4748

@@ -52,6 +53,9 @@ func GetPreferencesWithDefaults(query *m.GetPreferencesWithDefaultsQuery) error
5253
if p.Timezone != "" {
5354
res.Timezone = p.Timezone
5455
}
56+
if p.Language != "" {
57+
res.Language = p.Language
58+
}
5559
if p.HomeDashboardId != 0 {
5660
res.HomeDashboardId = p.HomeDashboardId
5761
}
@@ -94,6 +98,7 @@ func SavePreferences(cmd *m.SavePreferencesCommand) error {
9498
TeamId: cmd.TeamId,
9599
HomeDashboardId: cmd.HomeDashboardId,
96100
Timezone: cmd.Timezone,
101+
Language: cmd.Language,
97102
Theme: cmd.Theme,
98103
Created: time.Now(),
99104
Updated: time.Now(),
@@ -104,6 +109,7 @@ func SavePreferences(cmd *m.SavePreferencesCommand) error {
104109
prefs.HomeDashboardId = cmd.HomeDashboardId
105110
prefs.Timezone = cmd.Timezone
106111
prefs.Theme = cmd.Theme
112+
prefs.Language = cmd.Language
107113
prefs.Updated = time.Now()
108114
prefs.Version += 1
109115
_, err = sess.ID(prefs.Id).AllCols().Update(&prefs)

pkg/setting/setting.go

+7
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ var (
129129
LoginHint string
130130
PasswordHint string
131131
DefaultTheme string
132+
DefaultLanguage string
132133
DisableLoginForm bool
133134
DisableSignoutMenu bool
134135
SignoutRedirectUrl string
@@ -794,6 +795,12 @@ func (cfg *Cfg) Load(args *CommandLineArgs) error {
794795
if err != nil {
795796
return err
796797
}
798+
799+
DefaultLanguage, err = valueAsString(users, "default_language", "")
800+
if err != nil {
801+
return err
802+
}
803+
797804
ExternalUserMngLinkUrl, err = valueAsString(users, "external_manage_link_url", "")
798805
if err != nil {
799806
return err

public/app/app.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import 'react-dom';
1313
import 'vendor/bootstrap/bootstrap';
1414
import 'vendor/angular-other/angular-strap';
1515

16+
import i18n from './core/i18n';
17+
1618
import $ from 'jquery';
1719
import angular from 'angular';
1820
import config from 'app/core/config';
@@ -56,6 +58,7 @@ export class GrafanaApp {
5658
preBootModules: any[] | null;
5759

5860
constructor() {
61+
console.log("Current: " + i18n.locale);
5962
addClassIfNoOverlayScrollbar('no-overlay-scrollbar');
6063
this.preBootModules = [];
6164
this.registerFunctions = {};
@@ -74,7 +77,6 @@ export class GrafanaApp {
7477

7578
init() {
7679
const app = angular.module('grafana', []);
77-
7880
setLocale(config.bootData.user.locale);
7981

8082
setMarkdownOptions({ sanitize: !config.disableSanitizeHtml });
@@ -143,6 +145,8 @@ export class GrafanaApp {
143145
coreModule.config(setupAngularRoutes);
144146
registerAngularDirectives();
145147

148+
149+
146150
// disable tool tip animation
147151
$.fn.tooltip.defaults.animation = false;
148152

@@ -171,6 +175,7 @@ export class GrafanaApp {
171175
}
172176

173177
initEchoSrv() {
178+
// LoadLanguage();
174179
setEchoSrv(new Echo({ debug: process.env.NODE_ENV === 'development' }));
175180

176181
ttiPolyfill.getFirstConsistentlyInteractive().then((tti: any) => {

public/app/core/components/Login/ChangePassword.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { ChangeEvent, PureComponent, SyntheticEvent } from 'react';
22
import { Tooltip } from '@grafana/ui';
33
import { AppEvents } from '@grafana/data';
44
import { e2e } from '@grafana/e2e';
5-
5+
import { Trans } from "react-i18next";
66
import appEvents from 'app/core/app_events';
77

88
interface Props {
@@ -80,7 +80,9 @@ export class ChangePassword extends PureComponent<Props, State> {
8080
return (
8181
<div className="login-inner-box" id="change-password-view">
8282
<div className="text-left login-change-password-info">
83-
<h5>Change Password</h5>
83+
<h5>
84+
<Trans>Change Password</Trans>
85+
</h5>
8486
Before you can get started with awesome dashboards we need you to make your account more secure by changing
8587
your password.
8688
<br />

public/app/core/components/PageHeader/PageHeader.tsx

+10-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import classNames from 'classnames';
33
import appEvents from 'app/core/app_events';
44
import { NavModel, NavModelItem, NavModelBreadcrumb } from '@grafana/data';
55
import { CoreEvents } from 'app/types';
6+
import { Trans } from "react-i18next";
67

78
export interface Props {
89
model: NavModel;
@@ -62,7 +63,7 @@ const Tabs = ({ main, customCss }: { main: NavModelItem; customCss: string }) =>
6263
<li className="gf-tabs-item" key={tab.url}>
6364
<a className={tabClasses} target={tab.target} href={tab.url}>
6465
<i className={tab.icon} />
65-
{tab.text}
66+
<Trans>{tab.text}</Trans>
6667
</a>
6768
</li>
6869
);
@@ -72,6 +73,7 @@ const Tabs = ({ main, customCss }: { main: NavModelItem; customCss: string }) =>
7273
};
7374

7475
const Navigation = ({ main }: { main: NavModelItem }) => {
76+
console.log(main);
7577
return (
7678
<nav>
7779
<SelectNav customCss="page-header__select-nav" main={main} />
@@ -104,7 +106,7 @@ export default class PageHeader extends React.Component<Props, any> {
104106
if (bc.url) {
105107
breadcrumbsResult.push(
106108
<a className="text-link" key={breadcrumbsResult.length} href={bc.url}>
107-
{bc.title}
109+
<Trans>{bc.title}</Trans>
108110
</a>
109111
);
110112
} else {
@@ -113,7 +115,9 @@ export default class PageHeader extends React.Component<Props, any> {
113115
}
114116
breadcrumbsResult.push(<span key={breadcrumbs.length + 1}> / {title}</span>);
115117

116-
return <h1 className="page-header__title">{breadcrumbsResult}</h1>;
118+
return <h1 className="page-header__title">
119+
{breadcrumbsResult}
120+
</h1>;
117121
}
118122

119123
renderHeaderTitle(main: NavModelItem) {
@@ -126,7 +130,9 @@ export default class PageHeader extends React.Component<Props, any> {
126130

127131
<div className="page-header__info-block">
128132
{this.renderTitle(main.text, main.breadcrumbs)}
129-
{main.subTitle && <div className="page-header__sub-title">{main.subTitle}</div>}
133+
{main.subTitle && <div className="page-header__sub-title">
134+
<Trans>{main.subTitle}</Trans>
135+
</div>}
130136
</div>
131137
</div>
132138
);

0 commit comments

Comments
 (0)