From 50aca35f98ddaf325772979e73a8e25ec7aa262b Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Wed, 5 Mar 2014 18:16:25 +0100 Subject: [PATCH] SONAR-5114 Modify client side application to support App WS Also add translation module --- .../resources/org/sonar/l10n/core.properties | 4 ++ sonar-server/karma.conf.js | 4 +- .../qualitygate/ws/QgateAppHandler.java | 9 +-- .../WEB-INF/app/views/layouts/_head.html.erb | 2 + .../app/views/measures/search.html.erb | 8 ++- .../app/views/quality_gates/index.html.erb | 27 ------- .../_quality_gate_actions_template.hbs.erb | 4 +- ...ity_gate_detail_condition_template.hbs.erb | 18 ++--- ...e_detail_conditions_empty_template.hbs.erb | 2 +- ...ty_gate_detail_conditions_template.hbs.erb | 16 ++--- ...uality_gate_detail_header_template.hbs.erb | 10 +-- ...lity_gate_detail_projects_template.hbs.erb | 4 +- .../_quality_gate_edit_template.hbs.erb | 16 ++--- ...y_gate_sidebar_list_empty_template.hbs.erb | 2 +- ...ty_gate_sidebar_list_item_template.hbs.erb | 2 +- .../common/handlebars-extensions.js | 18 +++-- .../webapp/javascripts/common/inputs.coffee | 12 ++-- .../main/webapp/javascripts/common/inputs.js | 12 ++-- .../javascripts/quality-gate/app.coffee | 15 ++-- .../webapp/javascripts/quality-gate/app.js | 13 +++- .../quality-gate-detail-condition-view.coffee | 6 +- .../quality-gate-detail-condition-view.js | 6 +- ...quality-gate-detail-conditions-view.coffee | 2 +- .../quality-gate-detail-conditions-view.js | 2 +- .../quality-gate-detail-header-view.coffee | 2 +- .../views/quality-gate-detail-header-view.js | 2 +- .../quality-gate-detail-projects-view.coffee | 12 ++-- .../quality-gate-detail-projects-view.js | 12 ++-- .../tests/common/inputsSpec.coffee | 7 +- .../javascripts/tests/common/inputsSpec.js | 11 +-- .../javascripts/tests/translateSpec.coffee | 70 +++++++++++++++++++ .../webapp/javascripts/tests/translateSpec.js | 68 ++++++++++++++++++ .../src/main/webapp/javascripts/translate.js | 42 +++++++++++ sonar-server/wro.xml | 2 + 34 files changed, 312 insertions(+), 130 deletions(-) create mode 100644 sonar-server/src/main/webapp/javascripts/tests/translateSpec.coffee create mode 100644 sonar-server/src/main/webapp/javascripts/tests/translateSpec.js create mode 100644 sonar-server/src/main/webapp/javascripts/translate.js 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 @@ 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 @@ 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 @@ {{#if canEdit}} {{else}} @@ -16,15 +16,15 @@ {{#if canEdit}} {{else}} - {{translate 'alerts.operator' op}} + {{t 'quality_gates.operator' op}} {{/if}} - + {{#if canEdit}} {{else}} @@ -32,7 +32,7 @@ {{/if}} - + {{#if canEdit}} {{else}} @@ -43,13 +43,13 @@ {{#if canEdit}} {{#if id}}
- - + +
{{else}}
- - <%= message('cancel') -%> + + {{t 'cancel'}}
{{/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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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.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 = $(''); 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 @@ /javascripts/third-party/select2.js /javascripts/select2-jquery-ui-fix.js + /javascripts/translate.js + /javascripts/widgets/widget.js /javascripts/widgets/bubble-chart.js /javascripts/widgets/timeline.js -- 2.39.5