aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties4
-rw-r--r--sonar-server/karma.conf.js4
-rw-r--r--sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java9
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/measures/search.html.erb8
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb27
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_actions_template.hbs.erb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_condition_template.hbs.erb18
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_empty_template.hbs.erb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_template.hbs.erb16
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_header_template.hbs.erb10
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_projects_template.hbs.erb4
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_edit_template.hbs.erb16
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_empty_template.hbs.erb2
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_item_template.hbs.erb2
-rw-r--r--sonar-server/src/main/webapp/javascripts/common/handlebars-extensions.js18
-rw-r--r--sonar-server/src/main/webapp/javascripts/common/inputs.coffee12
-rw-r--r--sonar-server/src/main/webapp/javascripts/common/inputs.js12
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/app.coffee15
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/app.js13
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.coffee6
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.js6
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.coffee2
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.js2
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.coffee2
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.js2
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.coffee12
-rw-r--r--sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.js12
-rw-r--r--sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.coffee7
-rw-r--r--sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.js11
-rw-r--r--sonar-server/src/main/webapp/javascripts/tests/translateSpec.coffee70
-rw-r--r--sonar-server/src/main/webapp/javascripts/tests/translateSpec.js68
-rw-r--r--sonar-server/src/main/webapp/javascripts/translate.js42
-rw-r--r--sonar-server/wro.xml2
34 files changed, 312 insertions, 130 deletions
diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
index de3fc835737..a03ed679bf6 100644
--- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
+++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
@@ -1655,6 +1655,10 @@ quality_gates.projects.all=All
quality_gates.projects.noResults=No Projects
quality_gates.projects.select_hint=Click to associate this project with the quality gate
quality_gates.projects.deselect_hint=Click to remove association between this project and the quality gate
+quality_gates.operator.LT=is less than
+quality_gates.operator.GT=is greater than
+quality_gates.operator.EQ=equals
+quality_gates.operator.NE=is not
#------------------------------------------------------------------------------
#
diff --git a/sonar-server/karma.conf.js b/sonar-server/karma.conf.js
index 6b69e1acd6c..09d37706938 100644
--- a/sonar-server/karma.conf.js
+++ b/sonar-server/karma.conf.js
@@ -27,6 +27,7 @@ module.exports = function(config) {
'third-party/jquery.js',
'third-party/underscore.js',
'third-party/require.js',
+ 'translate.js',
'common/inputs.js',
// libs
@@ -57,7 +58,8 @@ module.exports = function(config) {
preprocessors: {
'navigator/**/*.js': 'coverage',
- 'common/inputs.js': 'coverage'
+ 'common/inputs.js': 'coverage',
+ 'translate.js': 'coverage'
},
diff --git a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java
index 7da851cab39..a9e1286173c 100644
--- a/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java
+++ b/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/QgateAppHandler.java
@@ -38,10 +38,6 @@ public class QgateAppHandler implements RequestHandler {
"alerts.notes.error",
"alerts.notes.ok",
"alerts.notes.warn",
- "alerts.operator.!=",
- "alerts.operator.<",
- "alerts.operator.=",
- "alerts.operator.>",
"alerts.select_metric",
"alerts.warn_tooltip",
"are_you_sure",
@@ -54,11 +50,16 @@ public class QgateAppHandler implements RequestHandler {
"name",
"quality_gates.add",
"quality_gates.add_condition",
+ "quality_gates.conditions",
"quality_gates.copy",
"quality_gates.health_icons",
"quality_gates.introduction",
"quality_gates.no_conditions",
"quality_gates.noQualityGates",
+ "quality_gates.operator.LT",
+ "quality_gates.operator.GT",
+ "quality_gates.operator.EQ",
+ "quality_gates.operator.NE",
"quality_gates.page",
"quality_gates.projects",
"quality_gates.projects.all",
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
index c569bfe5a2d..f1dc7f7d8be 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb
@@ -45,6 +45,8 @@
<%= javascript_include_tag 'third-party/select2' %>
<%= javascript_include_tag 'select2-jquery-ui-fix' %>
+ <%= javascript_include_tag 'translate' %>
+
<%= javascript_include_tag 'widgets/widget' %>
<%= javascript_include_tag 'widgets/bubble-chart' %>
<%= javascript_include_tag 'widgets/timeline' %>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/measures/search.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/measures/search.html.erb
index c8a91047d5b..d056480a983 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/measures/search.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/measures/search.html.erb
@@ -91,7 +91,13 @@
'warning': '<%= escape_javascript message('measure_filter.criteria.alert.warn') -%>',
'ok': '<%= escape_javascript message('measure_filter.criteria.alert.ok') -%>',
'days': '<%= escape_javascript message('measure_filter.criteria.age.days') -%>',
- 'filtersList': '<%= escape_javascript message('measure_filter.filter_list') -%>'
+ 'filtersList': '<%= escape_javascript message('measure_filter.filter_list') -%>',
+
+ 'work_duration': {
+ 'x_days': '<%= escape_javascript message('work_duration.x_days') -%>',
+ 'x_hours': '<%= escape_javascript message('work_duration.x_hours') -%>',
+ 'x_minutes': '<%= escape_javascript message('work_duration.x_minutes') -%>'
+ }
}
});
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb
index ff814fc9ccb..5402dcae379 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/index.html.erb
@@ -21,37 +21,10 @@
<script>
window.SS = {
- metricPeriods: [
- { key: '1', text: '<%= Api::Utils.period_label(1) -%>' },
- { key: '2', text: '<%= Api::Utils.period_label(2) -%>' },
- { key: '3', text: '<%= Api::Utils.period_label(3) -%>' }
- ],
-
workDuration: {
days: '<%= message('work_duration.x_days') -%>',
hours: '<%= message('work_duration.x_hours') -%>',
minutes: '<%= message('work_duration.x_minutes') -%>'
- },
-
- phrases: {
- areYouSure: '<%= message('are_you_sure') -%>',
- alerts: {
- operator: {
- 'LT': '<%= message('alerts.operator.<') -%>',
- 'GT': '<%= message('alerts.operator.>') -%>',
- 'EQ': '<%= message('alerts.operator.=') -%>',
- 'NE': '<%= message('alerts.operator.!=') -%>'
- },
- select_metric: '<%= message('alerts.select_metric') -%>'
- },
- projects: {
- 'with': '<%= message('quality_gates.projects.with') -%>',
- without: '<%= message('quality_gates.projects.without') -%>',
- all: '<%= message('quality_gates.projects.all') -%>',
- select_hint: '<%= message('quality_gates.projects.select_hint') -%>',
- deselect_hint: '<%= message('quality_gates.projects.deselect_hint') -%>',
- noResults: '<%= message('quality_gates.projects.noResults') -%>'
- }
}
};
</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_actions_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_actions_template.hbs.erb
index 1b27f7dcc56..083091f5e25 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_actions_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_actions_template.hbs.erb
@@ -1,8 +1,8 @@
<script id="quality-gate-actions-template" type="text/x-handlebars-template">
- <h1 class="navigator-header-title"><%= message('quality_gates.page') -%></h1>
+ <h1 class="navigator-header-title">{{t 'quality_gates.page'}}</h1>
{{#if canEdit}}
<div class="navigator-header-actions button-group">
- <button id="quality-gate-add"><%= message('add_verb') -%></button>
+ <button id="quality-gate-add">{{t 'add_verb'}}</button>
</div>
{{/if}}
</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_condition_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_condition_template.hbs.erb
index 0458e7e3571..cbc78673732 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_condition_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_condition_template.hbs.erb
@@ -5,7 +5,7 @@
<td width="10%" nowrap>
{{#if canEdit}}
<select name="period">
- <option value="0"><%= message('value') -%></option>
+ <option value="0">{{t 'value'}}</option>
{{#each periods}}<option value="{{key}}">{{text}}</option>{{/each}}
</select>
{{else}}
@@ -16,15 +16,15 @@
{{#if canEdit}}
<select name="operator">
{{#operators metric.type}}
- <option value="{{this}}">{{translate 'alerts.operator' this}}</option>
+ <option value="{{this}}">{{t 'quality_gates.operator' this}}</option>
{{/operators}}
</select>
{{else}}
- {{translate 'alerts.operator' op}}
+ {{t 'quality_gates.operator' op}}
{{/if}}
</td>
<td width="15%">
- <i class="icon-alert-warn" title="<%= message('alerts.warn_tooltip') -%>"></i>
+ <i class="icon-alert-warn" title="{{t 'alerts.warn_tooltip'}}"></i>
{{#if canEdit}}
<input name="warning" class="measure-input" data-type="{{metric.type}}" type="text">
{{else}}
@@ -32,7 +32,7 @@
{{/if}}
</td>
<td width="15%">
- <i class="icon-alert-error" title="<%= message('alerts.error_tooltip') -%>"></i>
+ <i class="icon-alert-error" title="{{t 'alerts.error_tooltip'}}"></i>
{{#if canEdit}}
<input name="error" class="measure-input" data-type="{{metric.type}}" type="text">
{{else}}
@@ -43,13 +43,13 @@
{{#if canEdit}}
{{#if id}}
<div class="button-group">
- <button class="update-condition" disabled><%= message('update_verb') -%></button>
- <button class="button-red delete-condition"><%= message('delete') -%></button>
+ <button class="update-condition" disabled>{{t 'update_verb'}}</button>
+ <button class="button-red delete-condition">{{t 'delete'}}</button>
</div>
{{else}}
<div class="button-group">
- <button class="add-condition"><%= message('add_verb') -%></button>
- <a class="action cancel-add-condition"><%= message('cancel') -%></a>
+ <button class="add-condition">{{t 'add_verb'}}</button>
+ <a class="action cancel-add-condition">{{t 'cancel'}}</a>
</div>
{{/if}}
{{/if}}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_empty_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_empty_template.hbs.erb
index 29e5ecd845f..038e0786fb5 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_empty_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_empty_template.hbs.erb
@@ -1,5 +1,5 @@
<script id="quality-gate-detail-conditions-empty-template" type="text/x-handlebars-template">
<td colspan="6">
- <%= message('quality_gates.no_conditions') -%>
+ {{t 'quality_gates.no_conditions'}}
</td>
</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_template.hbs.erb
index 047d12c147a..1ff680bc484 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_conditions_template.hbs.erb
@@ -1,12 +1,12 @@
<script id="quality-gate-detail-conditions-template" type="text/x-handlebars-template">
- <div class="quality-gate-section-name"><%= message('quality_gates.conditions') -%></div>
+ <div class="quality-gate-section-name">{{t 'quality_gates.conditions'}}</div>
<div class="quality-gate-introduction">
- <p><%= message('quality_gates.introduction') -%>
- <a class="link-action quality-gate-introduction-show-more"><%= message('more') -%></a>
+ <p>{{t 'quality_gates.introduction'}}
+ <a class="link-action quality-gate-introduction-show-more">{{t 'more'}}</a>
</p>
<div class="quality-gate-introduction-more">
- <%= message('quality_gates.health_icons') -%>
+ {{t 'quality_gates.health_icons'}}
<table class="data">
<thead>
<tr>
@@ -16,15 +16,15 @@
<tbody>
<tr class="even">
<td><i class="icon-alert-ok"></i></td>
- <td><%= message('alerts.notes.ok') -%></td>
+ <td>{{t 'alerts.notes.ok'}}</td>
</tr>
<tr class="odd">
<td><i class="icon-alert-warn"></i></td>
- <td><%= message('alerts.notes.warn') -%></td>
+ <td>{{t 'alerts.notes.warn'}}</td>
</tr>
<tr class="even">
<td><i class="icon-alert-error"></i></td>
- <td><%= message('alerts.notes.error') -%></td>
+ <td>{{t 'alerts.notes.error'}}</td>
</tr>
</tbody>
</table>
@@ -33,7 +33,7 @@
{{#if canEdit}}
<div class="quality-gate-new-condition">
- <label for="quality-gate-new-condition-metric"><%= message('quality_gates.add_condition') -%>:</label>
+ <label for="quality-gate-new-condition-metric">{{t 'quality_gates.add_condition'}}:</label>
<select id="quality-gate-new-condition-metric">
<option></option>
{{#each metricGroups}}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_header_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_header_template.hbs.erb
index 151c9f1ad03..7d4274c9de8 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_header_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_header_template.hbs.erb
@@ -3,14 +3,14 @@
{{#if canEdit}}
<div class="navigator-header-actions button-group">
- <button id="quality-gate-rename"><%= message('rename') -%></button>
- <button id="quality-gate-copy"><%= message('copy') -%></button>
+ <button id="quality-gate-rename">{{t 'rename'}}</button>
+ <button id="quality-gate-copy">{{t 'copy'}}</button>
{{#if default}}
- <button id="quality-gate-unset-as-default"><%= message('unset_as_default') -%></button>
+ <button id="quality-gate-unset-as-default">{{t 'unset_as_default'}}</button>
{{else}}
- <button id="quality-gate-set-as-default"><%= message('set_as_default') -%></button>
+ <button id="quality-gate-set-as-default">{{t 'set_as_default'}}</button>
{{/if}}
- <button id="quality-gate-delete" class="button-red"><%= message('delete') -%></button>
+ <button id="quality-gate-delete" class="button-red">{{t 'delete'}}</button>
</div>
{{/if}}
</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_projects_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_projects_template.hbs.erb
index 64e599cdb4c..9f107237684 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_projects_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_detail_projects_template.hbs.erb
@@ -1,8 +1,8 @@
<script id="quality-gate-detail-projects-template" type="text/x-handlebars-template">
- <div class="quality-gate-section-name"><%= message('quality_gates.projects') -%></div>
+ <div class="quality-gate-section-name">{{t 'quality_gates.projects'}}</div>
{{#if default}}
- <p><%= message('quality_gates.projects_for_default') -%></p>
+ <p>{{t 'quality_gates.projects_for_default'}}</p>
{{else}}
<div id="select-list-projects"></div>
{{/if}}
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_edit_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_edit_template.hbs.erb
index 34b12f6ebef..592da39d1bc 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_edit_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_edit_template.hbs.erb
@@ -1,24 +1,24 @@
<script id="quality-gate-edit-template" type="text/x-handlebars-template">
<form>
<div class="modal-head">
- {{#eq method "rename"}}<h2><%= message('quality_gates.rename') -%> {{name}}</h2>{{/eq}}
- {{#eq method "copy"}}<h2><%= message('quality_gates.copy') -%> {{name}}</h2>{{/eq}}
- {{#eq method "create"}}<h2><%= message('quality_gates.add') -%></h2>{{/eq}}
+ {{#eq method "rename"}}<h2>{{t 'quality_gates.rename'}} {{name}}</h2>{{/eq}}
+ {{#eq method "copy"}}<h2>{{t 'quality_gates.copy'}} {{name}}</h2>{{/eq}}
+ {{#eq method "create"}}<h2>{{t 'quality_gates.add'}}</h2>{{/eq}}
</div>
<div class="modal-body">
<div class="modal-error"></div>
<div class="modal-field">
- <label for="quality-gate-edit-name"><%= message('name') -%> <em class="mandatory">*</em></label>
+ <label for="quality-gate-edit-name">{{t 'name'}} <em class="mandatory">*</em></label>
<input id="quality-gate-edit-name" type="text" size="50" maxlength="100">
</div>
</div>
<div class="modal-foot">
- {{#eq method "rename"}}<button><%= message('save') -%></button>{{/eq}}
- {{#eq method "copy"}}<button><%= message('copy') -%></button>{{/eq}}
- {{#eq method "create"}}<button><%= message('create') -%></button>{{/eq}}
- <a id="quality-gate-cancel-create" class="action"><%= message('cancel') -%></a>
+ {{#eq method "rename"}}<button>{{t 'save'}}</button>{{/eq}}
+ {{#eq method "copy"}}<button>{{t 'copy'}}</button>{{/eq}}
+ {{#eq method "create"}}<button>{{t 'create'}}</button>{{/eq}}
+ <a id="quality-gate-cancel-create" class="action">{{t 'cancel'}}</a>
</div>
</form>
</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_empty_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_empty_template.hbs.erb
index 5fe429c3f24..9daa6f315a9 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_empty_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_empty_template.hbs.erb
@@ -1,3 +1,3 @@
<script id="quality-gate-sidebar-list-empty-template" type="text/x-handlebars-template">
- <div class="line line-nowrap"><%= message('quality_gates.noQualityGates') -%></div>
+ <div class="line line-nowrap">{{t 'quality_gates.noQualityGates'}}</div>
</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_item_template.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_item_template.hbs.erb
index 262c0be5956..7d75b457ec4 100644
--- a/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_item_template.hbs.erb
+++ b/sonar-server/src/main/webapp/WEB-INF/app/views/quality_gates/templates/_quality_gate_sidebar_list_item_template.hbs.erb
@@ -1,3 +1,3 @@
<script id="quality-gate-sidebar-list-item-template" type="text/x-handlebars-template">
- <div class="line line-nowrap">{{name}} {{#if default}}<span class="subtitle">(<%= message('default') -%>)</span>{{/if}}</div>
+ <div class="line line-nowrap">{{name}} {{#if default}}<span class="subtitle">({{t 'default'}})</span>{{/if}}</div>
</script>
diff --git a/sonar-server/src/main/webapp/javascripts/common/handlebars-extensions.js b/sonar-server/src/main/webapp/javascripts/common/handlebars-extensions.js
index 87b650dbe28..74d02784d06 100644
--- a/sonar-server/src/main/webapp/javascripts/common/handlebars-extensions.js
+++ b/sonar-server/src/main/webapp/javascripts/common/handlebars-extensions.js
@@ -82,16 +82,14 @@ define(['handlebars'], function (Handlebars) {
return url;
});
- Handlebars.registerHelper('translate', function(key, prefix) {
- var args = Array.prototype.slice.call(arguments, 0, -1),
- tokens = args.reduce(function(prev, current) {
- return prev.concat(current.split('.'));
- }, []),
- start = window.SS.phrases;
-
- return tokens.reduce(function(prev, current) {
- return current ? prev[current] : prev;
- }, start);
+ Handlebars.registerHelper('translate', function() {
+ var args = Array.prototype.slice.call(arguments, 0, -1);
+ return window.translate.apply(this, args);
+ });
+
+ Handlebars.registerHelper('t', function() {
+ var args = Array.prototype.slice.call(arguments, 0, -1);
+ return window.t.apply(this, args);
});
Handlebars.registerHelper('pluginActions', function(actions, options) {
diff --git a/sonar-server/src/main/webapp/javascripts/common/inputs.coffee b/sonar-server/src/main/webapp/javascripts/common/inputs.coffee
index c914068b9e4..4352040b021 100644
--- a/sonar-server/src/main/webapp/javascripts/common/inputs.coffee
+++ b/sonar-server/src/main/webapp/javascripts/common/inputs.coffee
@@ -5,9 +5,9 @@ transformPattern = (pattern) ->
convertWorkDuration = (value) ->
- daysPattern = transformPattern window.SS.workDuration.days
- hoursPattern = transformPattern window.SS.workDuration.hours
- minutesPattern = transformPattern window.SS.workDuration.minutes
+ daysPattern = transformPattern t('work_duration.x_days')
+ hoursPattern = transformPattern t('work_duration.x_hours')
+ minutesPattern = transformPattern t('work_duration.x_minutes')
days = value.match daysPattern
hours = value.match hoursPattern
@@ -29,9 +29,9 @@ restoreWorkDuration = (value) ->
hours = Math.floor((value - days * 8 * 60) / 60)
minutes = value % 60
result = []
- result.push window.SS.workDuration.days.replace('{0}', days) if days > 0
- result.push window.SS.workDuration.hours.replace('{0}', hours) if hours > 0
- result.push window.SS.workDuration.minutes.replace('{0}', minutes) if minutes > 0
+ result.push t('work_duration.x_days').replace('{0}', days) if days > 0
+ result.push t('work_duration.x_hours').replace('{0}', hours) if hours > 0
+ result.push t('work_duration.x_minutes').replace('{0}', minutes) if minutes > 0
result.join ' '
diff --git a/sonar-server/src/main/webapp/javascripts/common/inputs.js b/sonar-server/src/main/webapp/javascripts/common/inputs.js
index 093116c9a57..d4c3b61fc84 100644
--- a/sonar-server/src/main/webapp/javascripts/common/inputs.js
+++ b/sonar-server/src/main/webapp/javascripts/common/inputs.js
@@ -10,9 +10,9 @@
convertWorkDuration = function(value) {
var days, daysPattern, hours, hoursPattern, minutes, minutesPattern;
- daysPattern = transformPattern(window.SS.workDuration.days);
- hoursPattern = transformPattern(window.SS.workDuration.hours);
- minutesPattern = transformPattern(window.SS.workDuration.minutes);
+ daysPattern = transformPattern(t('work_duration.x_days'));
+ hoursPattern = transformPattern(t('work_duration.x_hours'));
+ minutesPattern = transformPattern(t('work_duration.x_minutes'));
days = value.match(daysPattern);
hours = value.match(hoursPattern);
minutes = value.match(minutesPattern);
@@ -36,13 +36,13 @@
minutes = value % 60;
result = [];
if (days > 0) {
- result.push(window.SS.workDuration.days.replace('{0}', days));
+ result.push(t('work_duration.x_days').replace('{0}', days));
}
if (hours > 0) {
- result.push(window.SS.workDuration.hours.replace('{0}', hours));
+ result.push(t('work_duration.x_hours').replace('{0}', hours));
}
if (minutes > 0) {
- result.push(window.SS.workDuration.minutes.replace('{0}', minutes));
+ result.push(t('work_duration.x_minutes').replace('{0}', minutes));
}
return result.join(' ');
};
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/app.coffee b/sonar-server/src/main/webapp/javascripts/quality-gate/app.coffee
index 346636af8a7..6c119104c12 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/app.coffee
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/app.coffee
@@ -125,13 +125,18 @@ requirejs [
App.openFirstQualityGate() if initial
- # Load metrics and the list of quality gates before start the application
+ # Call app, Load metrics and the list of quality gates before start the application
+ appXHR = jQuery.ajax
+ url: "#{baseUrl}/api/qualitygates/app"
+ .done (r) =>
+ App.canEdit = r.edit
+ App.periods = r.periods
+ window.messages = r.messages
+
qualityGatesXHR = App.qualityGates.fetch()
- jQuery.when(App.metrics.fetch(), qualityGatesXHR)
- .done ->
- # Set permissions
- App.canEdit = qualityGatesXHR.responseJSON.edit
+ jQuery.when(App.metrics.fetch(), qualityGatesXHR, appXHR)
+ .done ->
# Remove the initial spinner
jQuery('.quality-gate-page-loader').remove()
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/app.js b/sonar-server/src/main/webapp/javascripts/quality-gate/app.js
index de8c167eb71..b72dfa17020 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/app.js
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/app.js
@@ -31,7 +31,8 @@
});
requirejs(['backbone', 'backbone.marionette', 'handlebars', 'quality-gate/collections/quality-gates', 'quality-gate/collections/metrics', 'quality-gate/views/quality-gate-sidebar-list-view', 'quality-gate/views/quality-gate-actions-view', 'quality-gate/views/quality-gate-edit-view', 'quality-gate/router', 'quality-gate/layout', 'common/handlebars-extensions'], function(Backbone, Marionette, Handlebars, QualityGates, Metrics, QualityGateSidebarListItemView, QualityGateActionsView, QualityGateEditView, QualityGateRouter, QualityGateLayout) {
- var App, qualityGatesXHR;
+ var App, appXHR, qualityGatesXHR,
+ _this = this;
jQuery.ajaxSetup({
error: function(jqXHR) {
var errorBox, text, _ref;
@@ -109,9 +110,15 @@
return App.openFirstQualityGate();
}
});
+ appXHR = jQuery.ajax({
+ url: "" + baseUrl + "/api/qualitygates/app"
+ }).done(function(r) {
+ App.canEdit = r.edit;
+ App.periods = r.periods;
+ return window.messages = r.messages;
+ });
qualityGatesXHR = App.qualityGates.fetch();
- return jQuery.when(App.metrics.fetch(), qualityGatesXHR).done(function() {
- App.canEdit = qualityGatesXHR.responseJSON.edit;
+ return jQuery.when(App.metrics.fetch(), qualityGatesXHR, appXHR).done(function() {
jQuery('.quality-gate-page-loader').remove();
return App.start();
});
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.coffee b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.coffee
index f60bd4439a1..bae22f95073 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.coffee
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.coffee
@@ -89,7 +89,7 @@ define [
deleteCondition: ->
- if confirm window.SS.phrases.areYouSure
+ if confirm t('are_you_sure')
@showSpinner()
@model.delete().done =>
@options.collectionView.updateConditions()
@@ -105,8 +105,8 @@ define [
serializeData: ->
- period = _.findWhere(window.SS.metricPeriods, key: '' + this.model.get('period'))
+ period = _.findWhere(@options.app.periods, key: '' + this.model.get('period'))
_.extend super,
canEdit: @options.app.canEdit
- periods: window.SS.metricPeriods
+ periods: @options.app.periods
periodText: period?.text
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.js b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.js
index 6e29ecc2db1..ddd499d7f64 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.js
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-condition-view.js
@@ -107,7 +107,7 @@
QualityGateDetailConditionView.prototype.deleteCondition = function() {
var _this = this;
- if (confirm(window.SS.phrases.areYouSure)) {
+ if (confirm(t('are_you_sure'))) {
this.showSpinner();
return this.model["delete"]().done(function() {
_this.options.collectionView.updateConditions();
@@ -126,12 +126,12 @@
QualityGateDetailConditionView.prototype.serializeData = function() {
var period;
- period = _.findWhere(window.SS.metricPeriods, {
+ period = _.findWhere(this.options.app.periods, {
key: '' + this.model.get('period')
});
return _.extend(QualityGateDetailConditionView.__super__.serializeData.apply(this, arguments), {
canEdit: this.options.app.canEdit,
- periods: window.SS.metricPeriods,
+ periods: this.options.app.periods,
periodText: period != null ? period.text : void 0
});
};
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.coffee b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.coffee
index 9e88a74ee9f..8fc8054abcd 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.coffee
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.coffee
@@ -49,7 +49,7 @@ define [
@ui.metricSelect.select2
allowClear: false,
width: '250px',
- placeholder: window.SS.phrases.alerts.select_metric
+ placeholder: t('alerts.select_metric')
groupedMetrics: ->
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.js b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.js
index a6a26c583fc..7a145e44594 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.js
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-conditions-view.js
@@ -55,7 +55,7 @@
return this.ui.metricSelect.select2({
allowClear: false,
width: '250px',
- placeholder: window.SS.phrases.alerts.select_metric
+ placeholder: t('alerts.select_metric')
});
};
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.coffee b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.coffee
index b5be79800a1..932de7a1e33 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.coffee
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.coffee
@@ -39,7 +39,7 @@ define [
deleteQualityGate: ->
- if confirm window.SS.phrases.areYouSure
+ if confirm t('are_you_sure')
@showSpinner()
jQuery.ajax
type: 'POST'
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.js b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.js
index d3dcdd93591..1ec05e1ea63 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.js
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-header-view.js
@@ -45,7 +45,7 @@
QualityGateDetailHeaderView.prototype.deleteQualityGate = function() {
var _this = this;
- if (confirm(window.SS.phrases.areYouSure)) {
+ if (confirm(t('are_you_sure'))) {
this.showSpinner();
return jQuery.ajax({
type: 'POST',
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.coffee b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.coffee
index 0d02f0bf298..70fbe8f261e 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.coffee
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.coffee
@@ -26,10 +26,10 @@ define [
selectParameter: 'projectId'
selectParameterValue: 'id'
labels:
- selected: window.SS.phrases.projects.with
- deselected: window.SS.phrases.projects.without
- all: window.SS.phrases.projects.all
- noResults: window.SS.phrases.projects.noResults
+ selected: t('quality_gates.projects.with')
+ deselected: t('quality_gates.projects.without')
+ all: t('quality_gates.projects.all')
+ noResults: t('quality_gates.projects.noResults')
tooltips:
- select: window.SS.phrases.projects.select_hint
- deselect: window.SS.phrases.projects.deselect_hint
+ select: t('quality_gates.projects.select_hint')
+ deselect: t('quality_gates.projects.deselect_hint')
diff --git a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.js b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.js
index 2da6868f81e..3c647112f03 100644
--- a/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.js
+++ b/sonar-server/src/main/webapp/javascripts/quality-gate/views/quality-gate-detail-projects-view.js
@@ -33,14 +33,14 @@
selectParameter: 'projectId',
selectParameterValue: 'id',
labels: {
- selected: window.SS.phrases.projects["with"],
- deselected: window.SS.phrases.projects.without,
- all: window.SS.phrases.projects.all,
- noResults: window.SS.phrases.projects.noResults
+ selected: t('quality_gates.projects.with'),
+ deselected: t('quality_gates.projects.without'),
+ all: t('quality_gates.projects.all'),
+ noResults: t('quality_gates.projects.noResults')
},
tooltips: {
- select: window.SS.phrases.projects.select_hint,
- deselect: window.SS.phrases.projects.deselect_hint
+ select: t('quality_gates.projects.select_hint'),
+ deselect: t('quality_gates.projects.deselect_hint')
}
});
}
diff --git a/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.coffee b/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.coffee
index 335d26b190b..d20983d9c65 100644
--- a/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.coffee
+++ b/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.coffee
@@ -3,9 +3,10 @@ $ = jQuery
describe 'WORK_DUR suite', ->
beforeEach ->
- window.SS =
- workDuration:
- days: '{0}d', hours: '{0}h', minutes: '{0}min'
+ window.SS = {}
+ window.SS.phrases =
+ 'work_duration':
+ 'x_days': '{0}d', 'x_hours': '{0}h', 'x_minutes': '{0}min'
@input = $('<input type="text">')
@input.appendTo $('body')
diff --git a/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.js b/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.js
index 8d83eb5bfc8..2278db2d672 100644
--- a/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.js
+++ b/sonar-server/src/main/webapp/javascripts/tests/common/inputsSpec.js
@@ -6,11 +6,12 @@
describe('WORK_DUR suite', function() {
beforeEach(function() {
- window.SS = {
- workDuration: {
- days: '{0}d',
- hours: '{0}h',
- minutes: '{0}min'
+ window.SS = {};
+ window.SS.phrases = {
+ 'work_duration': {
+ 'x_days': '{0}d',
+ 'x_hours': '{0}h',
+ 'x_minutes': '{0}min'
}
};
this.input = $('<input type="text">');
diff --git a/sonar-server/src/main/webapp/javascripts/tests/translateSpec.coffee b/sonar-server/src/main/webapp/javascripts/tests/translateSpec.coffee
new file mode 100644
index 00000000000..24185180c23
--- /dev/null
+++ b/sonar-server/src/main/webapp/javascripts/tests/translateSpec.coffee
@@ -0,0 +1,70 @@
+$ = jQuery
+
+describe 'translation "t" suite', ->
+
+ beforeEach ->
+ window.messages =
+ 'something': 'SOMETHING'
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE'
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+
+ window.SS =
+ phrases:
+ 'something': 'SOMETHING ANOTHER'
+
+
+ afterEach ->
+ window.messages = window.SS = undefined
+
+
+ it 'translates', ->
+ expect(t('something')).toBe 'SOMETHING'
+
+
+ it 'translates with underscore', ->
+ expect(t('something_with_underscore')).toBe 'SOMETHING_WITH_UNDERSCORE'
+
+
+ it 'translates with braces', ->
+ expect(t('something_with{braces}')).toBe 'SOMETHING_WITH{braces}'
+
+
+ it 'fallbacks to "translate"', ->
+ window.messages = undefined
+ expect(t('something')).toBe 'SOMETHING ANOTHER'
+
+
+ it 'returns the key when no translation', ->
+ expect(t('something_another')).toBe 'something_another'
+
+
+
+describe 'translation "translate" suite', ->
+
+ beforeEach ->
+ window.SS =
+ phrases:
+ 'something': 'SOMETHING'
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE'
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+
+
+ afterEach ->
+ window.messages = window.SS = undefined
+
+
+ it 'translates', ->
+ expect(translate('something')).toBe 'SOMETHING'
+
+
+ it 'translates with underscore', ->
+ expect(translate('something_with_underscore')).toBe 'SOMETHING_WITH_UNDERSCORE'
+
+
+ it 'translates with braces', ->
+ expect(translate('something_with{braces}')).toBe 'SOMETHING_WITH{braces}'
+
+
+ it 'returns the key when no translation', ->
+ expect(translate('something_another')).toBe 'something_another'
+
diff --git a/sonar-server/src/main/webapp/javascripts/tests/translateSpec.js b/sonar-server/src/main/webapp/javascripts/tests/translateSpec.js
new file mode 100644
index 00000000000..b634742ec8d
--- /dev/null
+++ b/sonar-server/src/main/webapp/javascripts/tests/translateSpec.js
@@ -0,0 +1,68 @@
+// Generated by CoffeeScript 1.6.3
+(function() {
+ var $;
+
+ $ = jQuery;
+
+ describe('translation "t" suite', function() {
+ beforeEach(function() {
+ window.messages = {
+ 'something': 'SOMETHING',
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE',
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+ };
+ return window.SS = {
+ phrases: {
+ 'something': 'SOMETHING ANOTHER'
+ }
+ };
+ });
+ afterEach(function() {
+ return window.messages = window.SS = void 0;
+ });
+ it('translates', function() {
+ return expect(t('something')).toBe('SOMETHING');
+ });
+ it('translates with underscore', function() {
+ return expect(t('something_with_underscore')).toBe('SOMETHING_WITH_UNDERSCORE');
+ });
+ it('translates with braces', function() {
+ return expect(t('something_with{braces}')).toBe('SOMETHING_WITH{braces}');
+ });
+ it('fallbacks to "translate"', function() {
+ window.messages = void 0;
+ return expect(t('something')).toBe('SOMETHING ANOTHER');
+ });
+ return it('returns the key when no translation', function() {
+ return expect(t('something_another')).toBe('something_another');
+ });
+ });
+
+ describe('translation "translate" suite', function() {
+ beforeEach(function() {
+ return window.SS = {
+ phrases: {
+ 'something': 'SOMETHING',
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE',
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+ }
+ };
+ });
+ afterEach(function() {
+ return window.messages = window.SS = void 0;
+ });
+ it('translates', function() {
+ return expect(translate('something')).toBe('SOMETHING');
+ });
+ it('translates with underscore', function() {
+ return expect(translate('something_with_underscore')).toBe('SOMETHING_WITH_UNDERSCORE');
+ });
+ it('translates with braces', function() {
+ return expect(translate('something_with{braces}')).toBe('SOMETHING_WITH{braces}');
+ });
+ return it('returns the key when no translation', function() {
+ return expect(translate('something_another')).toBe('something_another');
+ });
+ });
+
+}).call(this);
diff --git a/sonar-server/src/main/webapp/javascripts/translate.js b/sonar-server/src/main/webapp/javascripts/translate.js
new file mode 100644
index 00000000000..3803a031c41
--- /dev/null
+++ b/sonar-server/src/main/webapp/javascripts/translate.js
@@ -0,0 +1,42 @@
+(function() {
+ var warn = function(message) {
+ if (console != null && typeof console.warn === 'function') {
+ console.warn(message);
+ }
+ };
+
+ window.t = function() {
+ if (!window.messages) {
+ return window.translate.apply(this, arguments);
+ }
+
+ var args = Array.prototype.slice.call(arguments, 0),
+ key = args.join('.');
+ if (!window.messages[key]) {
+ warn('No translation for "' + key + '"');
+ }
+ return (window.messages && window.messages[key]) || key;
+ };
+
+
+ window.translate = function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ tokens = args.reduce(function(prev, current) {
+ return prev.concat(current.split('.'));
+ }, []),
+ key = tokens.join('.'),
+ start = window.SS.phrases,
+ found = true;
+
+ var result = tokens.reduce(function(prev, current) {
+ if (!current || !prev[current]) {
+ warn('No translation for "' + key + '"');
+ found = false;
+ }
+ return current ? prev[current] : prev;
+ }, start);
+
+ return found ? result : key;
+ };
+
+})();
diff --git a/sonar-server/wro.xml b/sonar-server/wro.xml
index 3bcadf2a340..649e4569f87 100644
--- a/sonar-server/wro.xml
+++ b/sonar-server/wro.xml
@@ -24,6 +24,8 @@
<js>/javascripts/third-party/select2.js</js>
<js>/javascripts/select2-jquery-ui-fix.js</js>
+ <js>/javascripts/translate.js</js>
+
<js>/javascripts/widgets/widget.js</js>
<js>/javascripts/widgets/bubble-chart.js</js>
<js>/javascripts/widgets/timeline.js</js>