feat(i18n): add the ability to change the application language

feat807-i18n
Anthony Lapenna 2017-08-18 10:51:46 +02:00
parent f9308406af
commit 1a2ed3a6a4
12 changed files with 64 additions and 11 deletions

View File

@ -125,6 +125,7 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL
portainer.LDAPSearchSettings{}, portainer.LDAPSearchSettings{},
}, },
}, },
Language: "en",
} }
if *flags.Templates != "" { if *flags.Templates != "" {

View File

@ -57,6 +57,7 @@ type (
DisplayExternalContributors bool `valid:""` DisplayExternalContributors bool `valid:""`
AuthenticationMethod int `valid:"required"` AuthenticationMethod int `valid:"required"`
LDAPSettings portainer.LDAPSettings `valid:""` LDAPSettings portainer.LDAPSettings `valid:""`
Language string `valid:"required"`
} }
putSettingsLDAPCheckRequest struct { putSettingsLDAPCheckRequest struct {
@ -114,6 +115,7 @@ func (handler *SettingsHandler) handlePutSettings(w http.ResponseWriter, r *http
BlackListedLabels: req.BlackListedLabels, BlackListedLabels: req.BlackListedLabels,
DisplayExternalContributors: req.DisplayExternalContributors, DisplayExternalContributors: req.DisplayExternalContributors,
LDAPSettings: req.LDAPSettings, LDAPSettings: req.LDAPSettings,
Language: req.Language,
} }
if req.AuthenticationMethod == 1 { if req.AuthenticationMethod == 1 {

View File

@ -75,6 +75,7 @@ type (
DisplayExternalContributors bool `json:"DisplayExternalContributors"` DisplayExternalContributors bool `json:"DisplayExternalContributors"`
AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"` AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"`
LDAPSettings LDAPSettings `json:"LDAPSettings"` LDAPSettings LDAPSettings `json:"LDAPSettings"`
Language string `json:"Language"`
} }
// User represents a user account. // User represents a user account.

View File

@ -8,24 +8,24 @@
<div class="row"> <div class="row">
<div class="col-lg-12 col-md-12 col-xs-12" ng-if="applicationState.endpoint.mode.provider !== 'DOCKER_SWARM'"> <div class="col-lg-12 col-md-12 col-xs-12" ng-if="applicationState.endpoint.mode.provider !== 'DOCKER_SWARM'">
<rd-widget> <rd-widget>
<rd-widget-header icon="fa-tachometer" title="Node info"></rd-widget-header> <rd-widget-header icon="fa-tachometer" title="DASHBOARD.WIDGET_NODE.TITLE"></rd-widget-header>
<rd-widget-body classes="no-padding"> <rd-widget-body classes="no-padding">
<table class="table"> <table class="table">
<tbody> <tbody>
<tr> <tr>
<td>{{ 'DASHBOARD.NODE_NAME' | translate }}</td> <td translate>DASHBOARD.WIDGET_NODE.NODE_NAME</td>
<td>{{ infoData.Name }}</td> <td>{{ infoData.Name }}</td>
</tr> </tr>
<tr> <tr>
<td>Docker version</td> <td translate>DASHBOARD.WIDGET_NODE.DOCKER_VERSION</td>
<td>{{ infoData.ServerVersion }}</td> <td>{{ infoData.ServerVersion }}</td>
</tr> </tr>
<tr> <tr>
<td>CPU</td> <td translate>DASHBOARD.WIDGET_NODE.CPU</td>
<td>{{ infoData.NCPU }}</td> <td>{{ infoData.NCPU }}</td>
</tr> </tr>
<tr> <tr>
<td>Memory</td> <td translate>DASHBOARD.WIDGET_NODE.MEMORY</td>
<td>{{ infoData.MemTotal|humansize }}</td> <td>{{ infoData.MemTotal|humansize }}</td>
</tr> </tr>
</tbody> </tbody>

View File

@ -11,6 +11,20 @@
<rd-widget-header icon="fa-cogs" title="Application settings"></rd-widget-header> <rd-widget-header icon="fa-cogs" title="Application settings"></rd-widget-header>
<rd-widget-body> <rd-widget-body>
<form class="form-horizontal"> <form class="form-horizontal">
<!-- language -->
<div class="col-sm-12 form-section-title">
Language
</div>
<div class="form-group">
<label for="lang" class="col-sm-2 col-lg-1 control-label text-left">Language</label>
<div class="col-sm-10 col-lg-11">
<select class="form-control" id="lang" ng-model="settings.Language">
<option value="en">English</option>
<option value="fr">Français</option>
</select>
</div>
</div>
<!-- !language -->
<!-- logo --> <!-- logo -->
<div class="col-sm-12 form-section-title"> <div class="col-sm-12 form-section-title">
Logo Logo

View File

@ -55,6 +55,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
.then(function success(data) { .then(function success(data) {
Notifications.success('Settings updated'); Notifications.success('Settings updated');
StateManager.updateLogo(settings.LogoURL); StateManager.updateLogo(settings.LogoURL);
StateManager.updateLang(settings.Language);
StateManager.updateExternalContributions(settings.DisplayExternalContributors); StateManager.updateExternalContributions(settings.DisplayExternalContributors);
if (resetForm) { if (resetForm) {
resetFormValues(); resetFormValues();

View File

@ -9,7 +9,7 @@ angular
classes: '@?' classes: '@?'
}, },
transclude: true, transclude: true,
template: '<div class="widget-header"><div class="row"><span ng-class="classes" class="pull-left"><i class="fa" ng-class="icon"></i> {{title}} </span><span ng-class="classes" class="pull-right" ng-transclude></span></div></div>', template: '<div class="widget-header"><div class="row"><span ng-class="classes" class="pull-left" translate><i class="fa" ng-class="icon"></i> {{title}} </span><span ng-class="classes" class="pull-right" ng-transclude></span></div></div>',
restrict: 'E' restrict: 'E'
}; };
return directive; return directive;

View File

@ -5,4 +5,5 @@ function SettingsViewModel(data) {
this.DisplayExternalContributors = data.DisplayExternalContributors; this.DisplayExternalContributors = data.DisplayExternalContributors;
this.AuthenticationMethod = data.AuthenticationMethod; this.AuthenticationMethod = data.AuthenticationMethod;
this.LDAPSettings = data.LDAPSettings; this.LDAPSettings = data.LDAPSettings;
this.Language = data.Language;
} }

View File

@ -1,5 +1,5 @@
angular.module('portainer.services') angular.module('portainer.services')
.factory('StateManager', ['$q', 'SystemService', 'InfoHelper', 'LocalStorage', 'SettingsService', 'StatusService', function StateManagerFactory($q, SystemService, InfoHelper, LocalStorage, SettingsService, StatusService) { .factory('StateManager', ['$q', 'TranslationService', 'SystemService', 'InfoHelper', 'LocalStorage', 'SettingsService', 'StatusService', function StateManagerFactory($q, TranslationService, SystemService, InfoHelper, LocalStorage, SettingsService, StatusService) {
'use strict'; 'use strict';
var manager = {}; var manager = {};
@ -24,6 +24,12 @@ angular.module('portainer.services')
LocalStorage.storeApplicationState(state.application); LocalStorage.storeApplicationState(state.application);
}; };
manager.updateLang = function(lang) {
state.application.lang = lang;
LocalStorage.storeApplicationState(state.application);
TranslationService.setLang(state.application.lang);
};
manager.updateExternalContributions = function(displayExternalContributors) { manager.updateExternalContributions = function(displayExternalContributors) {
state.application.displayExternalContributors = displayExternalContributors; state.application.displayExternalContributors = displayExternalContributors;
LocalStorage.storeApplicationState(state.application); LocalStorage.storeApplicationState(state.application);
@ -41,6 +47,7 @@ angular.module('portainer.services')
if (applicationState) { if (applicationState) {
state.application = applicationState; state.application = applicationState;
state.loading = false; state.loading = false;
TranslationService.setLang(state.application.lang);
deferred.resolve(state); deferred.resolve(state);
} else { } else {
$q.all({ $q.all({
@ -55,8 +62,10 @@ angular.module('portainer.services')
state.application.endpointManagement = status.EndpointManagement; state.application.endpointManagement = status.EndpointManagement;
state.application.version = status.Version; state.application.version = status.Version;
state.application.logo = settings.LogoURL; state.application.logo = settings.LogoURL;
state.application.lang = settings.Language;
state.application.displayExternalContributors = settings.DisplayExternalContributors; state.application.displayExternalContributors = settings.DisplayExternalContributors;
LocalStorage.storeApplicationState(state.application); LocalStorage.storeApplicationState(state.application);
TranslationService.setLang(state.application.lang);
deferred.resolve(state); deferred.resolve(state);
}) })
.catch(function error(err) { .catch(function error(err) {

View File

@ -0,0 +1,12 @@
angular.module('portainer.services')
.factory('TranslationService', ['$translate', function TranslationServiceFactory($translate) {
'use strict';
var service = {};
service.setLang = function(lang) {
$translate.use(lang);
};
return service;
}]);

View File

@ -1,5 +1,11 @@
{ {
"DASHBOARD": { "DASHBOARD": {
"NODE_NAME": "Name" "WIDGET_NODE": {
"TITLE": "Node info",
"NODE_NAME": "Name",
"DOCKER_VERSION": "Docker version",
"CPU": "CPU",
"MEMORY": "Memory"
} }
}
} }

View File

@ -1,5 +1,11 @@
{ {
"DASHBOARD": { "DASHBOARD": {
"NODE_NAME": "Nom" "WIDGET_NODE": {
"TITLE": "Informations à propos de l'hôte",
"NODE_NAME": "Nom",
"DOCKER_VERSION": "Version de Docker",
"CPU": "Processeurs",
"MEMORY": "Mémoire"
} }
}
} }