mirror of https://github.com/portainer/portainer
feat(i18n): add the ability to change the application language
parent
f9308406af
commit
1a2ed3a6a4
|
@ -125,6 +125,7 @@ func initSettings(settingsService portainer.SettingsService, flags *portainer.CL
|
|||
portainer.LDAPSearchSettings{},
|
||||
},
|
||||
},
|
||||
Language: "en",
|
||||
}
|
||||
|
||||
if *flags.Templates != "" {
|
||||
|
|
|
@ -57,6 +57,7 @@ type (
|
|||
DisplayExternalContributors bool `valid:""`
|
||||
AuthenticationMethod int `valid:"required"`
|
||||
LDAPSettings portainer.LDAPSettings `valid:""`
|
||||
Language string `valid:"required"`
|
||||
}
|
||||
|
||||
putSettingsLDAPCheckRequest struct {
|
||||
|
@ -114,6 +115,7 @@ func (handler *SettingsHandler) handlePutSettings(w http.ResponseWriter, r *http
|
|||
BlackListedLabels: req.BlackListedLabels,
|
||||
DisplayExternalContributors: req.DisplayExternalContributors,
|
||||
LDAPSettings: req.LDAPSettings,
|
||||
Language: req.Language,
|
||||
}
|
||||
|
||||
if req.AuthenticationMethod == 1 {
|
||||
|
|
|
@ -75,6 +75,7 @@ type (
|
|||
DisplayExternalContributors bool `json:"DisplayExternalContributors"`
|
||||
AuthenticationMethod AuthenticationMethod `json:"AuthenticationMethod"`
|
||||
LDAPSettings LDAPSettings `json:"LDAPSettings"`
|
||||
Language string `json:"Language"`
|
||||
}
|
||||
|
||||
// User represents a user account.
|
||||
|
|
|
@ -8,24 +8,24 @@
|
|||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-xs-12" ng-if="applicationState.endpoint.mode.provider !== 'DOCKER_SWARM'">
|
||||
<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">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ 'DASHBOARD.NODE_NAME' | translate }}</td>
|
||||
<td translate>DASHBOARD.WIDGET_NODE.NODE_NAME</td>
|
||||
<td>{{ infoData.Name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Docker version</td>
|
||||
<td translate>DASHBOARD.WIDGET_NODE.DOCKER_VERSION</td>
|
||||
<td>{{ infoData.ServerVersion }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CPU</td>
|
||||
<td translate>DASHBOARD.WIDGET_NODE.CPU</td>
|
||||
<td>{{ infoData.NCPU }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Memory</td>
|
||||
<td translate>DASHBOARD.WIDGET_NODE.MEMORY</td>
|
||||
<td>{{ infoData.MemTotal|humansize }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -11,6 +11,20 @@
|
|||
<rd-widget-header icon="fa-cogs" title="Application settings"></rd-widget-header>
|
||||
<rd-widget-body>
|
||||
<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 -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Logo
|
||||
|
|
|
@ -55,6 +55,7 @@ function ($scope, $state, Notifications, SettingsService, StateManager, DEFAULT_
|
|||
.then(function success(data) {
|
||||
Notifications.success('Settings updated');
|
||||
StateManager.updateLogo(settings.LogoURL);
|
||||
StateManager.updateLang(settings.Language);
|
||||
StateManager.updateExternalContributions(settings.DisplayExternalContributors);
|
||||
if (resetForm) {
|
||||
resetFormValues();
|
||||
|
|
|
@ -9,7 +9,7 @@ angular
|
|||
classes: '@?'
|
||||
},
|
||||
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'
|
||||
};
|
||||
return directive;
|
||||
|
|
|
@ -5,4 +5,5 @@ function SettingsViewModel(data) {
|
|||
this.DisplayExternalContributors = data.DisplayExternalContributors;
|
||||
this.AuthenticationMethod = data.AuthenticationMethod;
|
||||
this.LDAPSettings = data.LDAPSettings;
|
||||
this.Language = data.Language;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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';
|
||||
|
||||
var manager = {};
|
||||
|
@ -24,6 +24,12 @@ angular.module('portainer.services')
|
|||
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) {
|
||||
state.application.displayExternalContributors = displayExternalContributors;
|
||||
LocalStorage.storeApplicationState(state.application);
|
||||
|
@ -41,6 +47,7 @@ angular.module('portainer.services')
|
|||
if (applicationState) {
|
||||
state.application = applicationState;
|
||||
state.loading = false;
|
||||
TranslationService.setLang(state.application.lang);
|
||||
deferred.resolve(state);
|
||||
} else {
|
||||
$q.all({
|
||||
|
@ -55,8 +62,10 @@ angular.module('portainer.services')
|
|||
state.application.endpointManagement = status.EndpointManagement;
|
||||
state.application.version = status.Version;
|
||||
state.application.logo = settings.LogoURL;
|
||||
state.application.lang = settings.Language;
|
||||
state.application.displayExternalContributors = settings.DisplayExternalContributors;
|
||||
LocalStorage.storeApplicationState(state.application);
|
||||
TranslationService.setLang(state.application.lang);
|
||||
deferred.resolve(state);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
|
|
|
@ -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;
|
||||
}]);
|
|
@ -1,5 +1,11 @@
|
|||
{
|
||||
"DASHBOARD": {
|
||||
"NODE_NAME": "Name"
|
||||
"DASHBOARD": {
|
||||
"WIDGET_NODE": {
|
||||
"TITLE": "Node info",
|
||||
"NODE_NAME": "Name",
|
||||
"DOCKER_VERSION": "Docker version",
|
||||
"CPU": "CPU",
|
||||
"MEMORY": "Memory"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
{
|
||||
"DASHBOARD": {
|
||||
"NODE_NAME": "Nom"
|
||||
"DASHBOARD": {
|
||||
"WIDGET_NODE": {
|
||||
"TITLE": "Informations à propos de l'hôte",
|
||||
"NODE_NAME": "Nom",
|
||||
"DOCKER_VERSION": "Version de Docker",
|
||||
"CPU": "Processeurs",
|
||||
"MEMORY": "Mémoire"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue