diff options
Diffstat (limited to 'server')
103 files changed, 458 insertions, 382 deletions
diff --git a/server/sonar-web/src/main/js/apps/account/change-password-view.js b/server/sonar-web/src/main/js/apps/account/change-password-view.js index f2cca1e60da..289c9e7ac7c 100644 --- a/server/sonar-web/src/main/js/apps/account/change-password-view.js +++ b/server/sonar-web/src/main/js/apps/account/change-password-view.js @@ -20,6 +20,7 @@ import $ from 'jquery'; import ModalForm from '../../components/common/modal-form'; import Template from './templates/account-change-password.hbs'; +import { translate } from '../../helpers/l10n'; export default ModalForm.extend({ template: Template, @@ -29,7 +30,7 @@ export default ModalForm.extend({ if (this.checkPasswords()) { this.sendRequest(); } else { - this.showErrors([{ msg: window.t('user.password_doesnt_match_confirmation') }]); + this.showErrors([{ msg: translate('user.password_doesnt_match_confirmation') }]); } }, diff --git a/server/sonar-web/src/main/js/apps/background-tasks/header.js b/server/sonar-web/src/main/js/apps/background-tasks/header.js index 2884f9e75fe..ebba7aa2dcf 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/header.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/header.js @@ -18,13 +18,14 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ render() { return ( <header className="page-header"> - <h1 className="page-title">{window.t('background_tasks.page')}</h1> - <p className="page-description">{window.t('background_tasks.page.description')}</p> + <h1 className="page-title">{translate('background_tasks.page')}</h1> + <p className="page-description">{translate('background_tasks.page.description')}</p> </header> ); } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/search.js b/server/sonar-web/src/main/js/apps/background-tasks/search.js index 1c2c3b50147..30cea9ad1e2 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/search.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/search.js @@ -22,6 +22,7 @@ import moment from 'moment'; import React from 'react'; import RadioToggle from '../../components/shared/radio-toggle'; import { STATUSES, CURRENTS, DATE, DATE_FORMAT } from './constants'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ componentDidMount() { @@ -34,25 +35,25 @@ export default React.createClass({ getCurrentsOptions() { return [ - { value: CURRENTS.ALL, label: window.t('background_tasks.currents_filter.ALL') }, - { value: CURRENTS.ONLY_CURRENTS, label: window.t('background_tasks.currents_filter.ONLY_CURRENTS') } + { value: CURRENTS.ALL, label: translate('background_tasks.currents_filter.ALL') }, + { value: CURRENTS.ONLY_CURRENTS, label: translate('background_tasks.currents_filter.ONLY_CURRENTS') } ]; }, getStatusOptions() { return [ - { value: STATUSES.ALL, label: window.t('background_task.status.ALL') }, - { value: STATUSES.SUCCESS, label: window.t('background_task.status.SUCCESS') }, - { value: STATUSES.FAILED, label: window.t('background_task.status.FAILED') }, - { value: STATUSES.CANCELED, label: window.t('background_task.status.CANCELED') } + { value: STATUSES.ALL, label: translate('background_task.status.ALL') }, + { value: STATUSES.SUCCESS, label: translate('background_task.status.SUCCESS') }, + { value: STATUSES.FAILED, label: translate('background_task.status.FAILED') }, + { value: STATUSES.CANCELED, label: translate('background_task.status.CANCELED') } ]; }, getDateOptions() { return [ - { value: DATE.ANY, label: window.t('background_tasks.date_filter.ALL') }, - { value: DATE.TODAY, label: window.t('background_tasks.date_filter.TODAY') }, - { value: DATE.CUSTOM, label: window.t('background_tasks.date_filter.CUSTOM') } + { value: DATE.ANY, label: translate('background_tasks.date_filter.ALL') }, + { value: DATE.TODAY, label: translate('background_tasks.date_filter.TODAY') }, + { value: DATE.CUSTOM, label: translate('background_tasks.date_filter.CUSTOM') } ]; }, @@ -158,7 +159,7 @@ export default React.createClass({ </li> <li>{this.renderSearchBox()}</li> <li className="pull-right"> - <button onClick={this.refresh} ref="reloadButton">{window.t('reload')}</button> + <button onClick={this.refresh} ref="reloadButton">{translate('reload')}</button> </li> </ul> </section> diff --git a/server/sonar-web/src/main/js/apps/background-tasks/stats.js b/server/sonar-web/src/main/js/apps/background-tasks/stats.js index 51410d559af..dc5b447f291 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/stats.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/stats.js @@ -21,6 +21,7 @@ import React from 'react'; import { formatDuration } from './helpers'; import { TooltipsMixin } from '../../components/mixins/tooltips-mixin'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ @@ -41,7 +42,7 @@ export default React.createClass({ return null; } return ( - <span className="huge-spacer-left" title={window.t('background_tasks.in_progress_duration')} + <span className="huge-spacer-left" title={translate('background_tasks.in_progress_duration')} data-toggle="tooltip"> <i className="spinner spacer-right" style={{ verticalAlign: 'text-top' }}/> <span ref="inProgressDuration" className="emphasised-measure"> @@ -60,9 +61,9 @@ export default React.createClass({ <span> <span ref="pendingCount" className="emphasised-measure">{this.props.pendingCount}</span> - {window.t('background_tasks.pending')} + {translate('background_tasks.pending')} <a ref="cancelPending" onClick={this.onPendingCanceled} className="icon-delete spacer-left" - title={window.t('background_tasks.cancel_all_tasks')} data-toggle="tooltip" href="#"></a> + title={translate('background_tasks.cancel_all_tasks')} data-toggle="tooltip" href="#"></a> </span> ); } else { @@ -70,7 +71,7 @@ export default React.createClass({ <span> <span ref="pendingCount" className="emphasised-measure">{this.props.pendingCount}</span> - {window.t('background_tasks.pending')} + {translate('background_tasks.pending')} </span> ); } @@ -95,7 +96,7 @@ export default React.createClass({ title="Count of projects where processing of most recent analysis report failed" href="#">{this.props.failuresCount}</a> - {window.t('background_tasks.failures')} + {translate('background_tasks.failures')} </span> ); } else { @@ -106,7 +107,7 @@ export default React.createClass({ {this.props.failuresCount} </span> - {window.t('background_tasks.failures')} + {translate('background_tasks.failures')} </span> ); } diff --git a/server/sonar-web/src/main/js/apps/background-tasks/tasks.js b/server/sonar-web/src/main/js/apps/background-tasks/tasks.js index 064b0a92d23..f93c7f0033c 100644 --- a/server/sonar-web/src/main/js/apps/background-tasks/tasks.js +++ b/server/sonar-web/src/main/js/apps/background-tasks/tasks.js @@ -26,6 +26,7 @@ import PendingIcon from '../../components/shared/pending-icon'; import { STATUSES } from './constants'; import { formatDuration } from './helpers'; import { TooltipsMixin } from '../../components/mixins/tooltips-mixin'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ @@ -55,18 +56,18 @@ export default React.createClass({ inner = <i className="spinner"/>; break; case STATUSES.SUCCESS: - inner = <span className="badge badge-success">{window.t('background_task.status.SUCCESS')}</span>; + inner = <span className="badge badge-success">{translate('background_task.status.SUCCESS')}</span>; break; case STATUSES.FAILED: - inner = <span className="badge badge-danger">{window.t('background_task.status.FAILED')}</span>; + inner = <span className="badge badge-danger">{translate('background_task.status.FAILED')}</span>; break; case STATUSES.CANCELED: - inner = <span className="badge badge-muted">{window.t('background_task.status.CANCELED')}</span>; + inner = <span className="badge badge-muted">{translate('background_task.status.CANCELED')}</span>; break; default: inner = ''; } - return <td className="thin spacer-right" title={window.t('background_task.status', task.status)} + return <td className="thin spacer-right" title={translate('background_task.status', task.status)} data-toggle="tooltip">{inner}</td>; }, @@ -125,7 +126,7 @@ export default React.createClass({ if (task.status === STATUSES.PENDING) { return ( <a onClick={this.onTaskCanceled.bind(this, task)} className="icon-delete" - title={window.t('background_tasks.cancel_task')} data-toggle="tooltip" href="#"></a> + title={translate('background_tasks.cancel_task')} data-toggle="tooltip" href="#"></a> ); } else { return null; @@ -135,7 +136,7 @@ export default React.createClass({ renderLogsLink(task) { if (task.logs) { let url = `${window.baseUrl}/api/ce/logs?taskId=${task.id}`; - return <a target="_blank" href={url}>{window.t('background_tasks.logs')}</a>; + return <a target="_blank" href={url}>{translate('background_tasks.logs')}</a>; } else { return null; } @@ -173,10 +174,10 @@ export default React.createClass({ <th> </th> <th> </th> <th> </th> - <th>{window.t('background_tasks.table.submitted')}</th> - <th>{window.t('background_tasks.table.started')}</th> - <th>{window.t('background_tasks.table.finished')}</th> - <th>{window.t('background_tasks.table.duration')}</th> + <th>{translate('background_tasks.table.submitted')}</th> + <th>{translate('background_tasks.table.started')}</th> + <th>{translate('background_tasks.table.finished')}</th> + <th>{translate('background_tasks.table.duration')}</th> <th> </th> </tr> </thead> diff --git a/server/sonar-web/src/main/js/apps/code/actions/index.js b/server/sonar-web/src/main/js/apps/code/actions/index.js index bfd5216f91b..d9edf8eca7b 100644 --- a/server/sonar-web/src/main/js/apps/code/actions/index.js +++ b/server/sonar-web/src/main/js/apps/code/actions/index.js @@ -22,6 +22,7 @@ import { pushPath } from 'redux-simple-router'; import { getChildren, getComponent, getTree } from '../../../api/components'; import { getComponentNavigation } from '../../../api/nav'; +import { translate } from '../../../helpers/l10n'; const METRICS = [ @@ -137,15 +138,15 @@ requestTree = _.debounce(requestTree, 250); async function getErrorMessage (response) { switch (response.status) { case 401: - return window.t('not_authorized'); + return translate('not_authorized'); default: try { let json = await response.json(); return json['err_msg'] || (json.errors && _.pluck(json.errors, 'msg').join('. ')) || - window.t('default_error_message'); + translate('default_error_message'); } catch (e) { - return window.t('default_error_message'); + return translate('default_error_message'); } } } @@ -186,5 +187,3 @@ export function search (query, baseComponent) { } }; } - - diff --git a/server/sonar-web/src/main/js/apps/code/components/Code.js b/server/sonar-web/src/main/js/apps/code/components/Code.js index 81f63740de2..9a2dc252558 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Code.js +++ b/server/sonar-web/src/main/js/apps/code/components/Code.js @@ -26,6 +26,7 @@ import Breadcrumbs from './Breadcrumbs'; import SourceViewer from './SourceViewer'; import Search from './Search'; import { initComponent, browse } from '../actions'; +import { translate } from '../../../helpers/l10n'; class Code extends Component { @@ -71,7 +72,7 @@ class Code extends Component { return ( <div className="page"> <header className="page-header"> - <h1 className="page-title">{window.t('code.page')}</h1> + <h1 className="page-title">{translate('code.page')}</h1> <div className="pull-left" diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js index 4d996238c35..37d6f62dc4e 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js @@ -20,13 +20,14 @@ import React from 'react'; import { getComponentUrl } from '../../../helpers/urls'; +import { translate } from '../../../helpers/l10n'; const ComponentDetach = ({ component }) => ( <a className="icon-detach" target="_blank" - title={window.t('code.open_in_new_tab')} + title={translate('code.open_in_new_tab')} href={getComponentUrl(component.key)}/> ); diff --git a/server/sonar-web/src/main/js/apps/code/components/Components.js b/server/sonar-web/src/main/js/apps/code/components/Components.js index 2ed8fb607e6..e86d1bf4b8b 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Components.js +++ b/server/sonar-web/src/main/js/apps/code/components/Components.js @@ -21,6 +21,7 @@ import React from 'react'; import Component from './Component'; import ComponentsEmpty from './ComponentsEmpty'; +import { translate } from '../../../helpers/l10n'; const Components = ({ baseComponent, components, coverageMetric, onBrowse }) => ( @@ -29,11 +30,11 @@ const Components = ({ baseComponent, components, coverageMetric, onBrowse }) => <tr> <th className="thin nowrap"> </th> <th> </th> - <th className="thin nowrap text-right">{window.t('metric.ncloc.name')}</th> - <th className="thin nowrap text-right">{window.t('metric.sqale_index.short_name')}</th> - <th className="thin nowrap text-right">{window.t('metric.violations.name')}</th> - <th className="thin nowrap text-right">{window.t('metric.coverage.name')}</th> - <th className="thin nowrap text-right">{window.t('metric.duplicated_lines_density.short_name')}</th> + <th className="thin nowrap text-right">{translate('metric.ncloc.name')}</th> + <th className="thin nowrap text-right">{translate('metric.sqale_index.short_name')}</th> + <th className="thin nowrap text-right">{translate('metric.violations.name')}</th> + <th className="thin nowrap text-right">{translate('metric.coverage.name')}</th> + <th className="thin nowrap text-right">{translate('metric.duplicated_lines_density.short_name')}</th> </tr> </thead> {baseComponent && ( diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js b/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js index f792add07ec..f6a5aa577a2 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentsEmpty.js @@ -18,12 +18,13 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; +import { translate } from '../../../helpers/l10n'; const ComponentsEmpty = () => ( <tr> <td colSpan="2"> - {window.t('no_results')} + {translate('no_results')} </td> <td colSpan="5"> diff --git a/server/sonar-web/src/main/js/apps/coding-rules/app.js b/server/sonar-web/src/main/js/apps/coding-rules/app.js index 80fe331f8d0..6e94452f88e 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/app.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/app.js @@ -31,6 +31,7 @@ import WorkspaceListView from './workspace-list-view'; import WorkspaceHeaderView from './workspace-header-view'; import FacetsView from './facets-view'; import FiltersView from './filters-view'; +import { translate } from '../../helpers/l10n'; var App = new Marionette.Application(), init = function () { @@ -80,7 +81,7 @@ var App = new Marionette.Application(), App.manualRepository = function () { return { key: 'manual', - name: window.t('coding_rules.manual_rule'), + name: translate('coding_rules.manual_rule'), language: 'none' }; }; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js index 68f32a1d2e1..893e7d44561 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/bulk-change-modal-view.js @@ -21,6 +21,7 @@ import $ from 'jquery'; import _ from 'underscore'; import ModalFormView from '../../components/common/modal-form'; import Template from './templates/coding-rules-bulk-change-modal.hbs'; +import { translateWithParameters } from '../../helpers/l10n'; export default ModalFormView.extend({ template: Template, @@ -34,14 +35,16 @@ export default ModalFormView.extend({ showSuccessMessage: function (profile, succeeded) { var profileBase = _.findWhere(this.options.app.qualityProfiles, { key: profile }), profileName = profileBase != null ? profileBase.name : profile, - message = window.tp('coding_rules.bulk_change.success', profileName, profileBase.language, succeeded); + message = translateWithParameters('coding_rules.bulk_change.success', + profileName, profileBase.language, succeeded); this.ui.messagesContainer.append('<div class="alert alert-success">' + message + '</div>'); }, showWarnMessage: function (profile, succeeded, failed) { var profileBase = _.findWhere(this.options.app.qualityProfiles, { key: profile }), profileName = profileBase != null ? profileBase.name : profile, - message = window.tp('coding_rules.bulk_change.warning', profileName, profileBase.language, succeeded, failed); + message = translateWithParameters('coding_rules.bulk_change.warning', + profileName, profileBase.language, succeeded, failed); this.ui.messagesContainer.append('<div class="alert alert-warning">' + message + '</div>'); }, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js index 855b1004c6d..99957a26d38 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/active-severity-facet.js @@ -20,6 +20,7 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; import Template from '../templates/facets/coding-rules-severity-facet.hbs'; +import { translate } from '../../../helpers/l10n'; export default BaseFacet.extend({ template: Template, @@ -45,7 +46,7 @@ export default BaseFacet.extend({ forbid: function () { BaseFacet.prototype.forbid.apply(this, arguments); - this.$el.prop('title', window.t('coding_rules.filters.active_severity.inactive')); + this.$el.prop('title', translate('coding_rules.filters.active_severity.inactive')); }, allow: function () { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js index 56ff71d1154..4ddbf74a624 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/custom-values-facet.js @@ -20,6 +20,7 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; import Template from '../templates/facets/coding-rules-custom-values-facet.hbs'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default BaseFacet.extend({ template: Template, @@ -41,17 +42,17 @@ export default BaseFacet.extend({ prepareSearch: function () { this.$('.js-custom-value').select2({ - placeholder: window.t('search_verb'), + placeholder: translate('search_verb'), minimumInputLength: 1, allowClear: false, formatNoMatches: function () { - return window.t('select2.noMatches'); + return translate('select2.noMatches'); }, formatSearching: function () { - return window.t('select2.searching'); + return translate('select2.searching'); }, formatInputTooShort: function () { - return window.tp('select2.tooShort', 1); + return translateWithParameters('select2.tooShort', 1); }, width: '100%', ajax: this.prepareAjaxSearch() diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js index 51926808077..ba48902164b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/inheritance-facet.js @@ -21,6 +21,7 @@ import $ from 'jquery'; import _ from 'underscore'; import BaseFacet from './base-facet'; import Template from '../templates/facets/coding-rules-inheritance-facet.hbs'; +import { translate } from '../../../helpers/l10n'; export default BaseFacet.extend({ template: Template, @@ -49,7 +50,7 @@ export default BaseFacet.extend({ forbid: function () { BaseFacet.prototype.forbid.apply(this, arguments); - this.$el.prop('title', window.t('coding_rules.filters.inheritance.inactive')); + this.$el.prop('title', translate('coding_rules.filters.inheritance.inactive')); }, allow: function () { @@ -61,7 +62,7 @@ export default BaseFacet.extend({ var values = ['NONE', 'INHERITED', 'OVERRIDES']; return values.map(function (key) { return { - label: window.t('coding_rules.filters.inheritance', key.toLowerCase()), + label: translate('coding_rules.filters.inheritance', key.toLowerCase()), val: key }; }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js index 03f833d2a51..43895033e86 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/facets/status-facet.js @@ -19,6 +19,7 @@ */ import _ from 'underscore'; import BaseFacet from './base-facet'; +import { translate } from '../../../helpers/l10n'; export default BaseFacet.extend({ statuses: ['READY', 'DEPRECATED', 'BETA'], @@ -26,7 +27,7 @@ export default BaseFacet.extend({ getValues: function () { var values = this.model.getValues(); var x = values.map(function (value) { - return _.extend(value, { label: window.t('rules.status', value.val.toLowerCase()) }); + return _.extend(value, { label: translate('rules.status', value.val.toLowerCase()) }); }); return x; }, diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js index c44456d9c13..8cff115d460 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule-details-view.js @@ -32,6 +32,7 @@ import CustomRuleCreationView from './rule/custom-rule-creation-view'; import IssuesView from './rule/rule-issues-view'; import Template from './templates/coding-rules-rule-details.hbs'; import confirmDialog from './confirm-dialog'; +import { translate, translateWithParameters } from '../../helpers/l10n'; export default Marionette.LayoutView.extend({ className: 'coding-rule-details', @@ -149,8 +150,8 @@ export default Marionette.LayoutView.extend({ var that = this, ruleType = this.model.has('templateKey') ? 'custom' : 'manual'; confirmDialog({ - title: window.t('delete'), - html: window.tp('coding_rules.delete.' + ruleType + '.confirm', this.model.get('name')), + title: translate('delete'), + html: translateWithParameters('coding_rules.delete.' + ruleType + '.confirm', this.model.get('name')), yesHandler: function () { var url = baseUrl + '/api/rules/delete', options = { key: that.model.id }; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js index 5f4cbc72378..2d89ec9d009 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-creation-view.js @@ -23,6 +23,7 @@ import ModalFormView from '../../../components/common/modal-form'; import Template from '../templates/rule/coding-rules-custom-rule-creation.hbs'; import { csvEscape } from '../../../helpers/csv'; import latinize from '../../../helpers/latinize'; +import { translate } from '../../../helpers/l10n'; export default ModalFormView.extend({ template: Template, @@ -172,7 +173,7 @@ export default ModalFormView.extend({ }).fail(function (jqXHR) { if (jqXHR.status === 409) { that.existingRule = jqXHR.responseJSON.rule; - that.showErrors([], [{ msg: window.t('coding_rules.reactivate.help') }]); + that.showErrors([], [{ msg: translate('coding_rules.reactivate.help') }]); that.ui.customRuleCreationCreate.addClass('hidden'); that.ui.customRuleCreationReactivate.removeClass('hidden'); } else { @@ -194,7 +195,7 @@ export default ModalFormView.extend({ var statuses = ['READY', 'BETA', 'DEPRECATED'].map(function (status) { return { id: status, - text: window.t('rules.status', status.toLowerCase()) + text: translate('rules.status', status.toLowerCase()) }; }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js index 6a0875adee6..f254c02c1b9 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/custom-rule-view.js @@ -22,6 +22,7 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import Template from '../templates/rule/coding-rules-custom-rule.hbs'; import confirmDialog from '../confirm-dialog'; +import { translate } from '../../../helpers/l10n'; export default Marionette.ItemView.extend({ tagName: 'tr', @@ -38,8 +39,8 @@ export default Marionette.ItemView.extend({ deleteRule: function () { var that = this; confirmDialog({ - title: window.t('delete'), - html: window.t('are_you_sure'), + title: translate('delete'), + html: translate('are_you_sure'), yesHandler: function () { var url = baseUrl + '/api/rules/delete', options = { key: that.model.id }; diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js index 3459339051f..8f177728063 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/manual-rule-creation-view.js @@ -22,6 +22,7 @@ import _ from 'underscore'; import ModalFormView from '../../../components/common/modal-form'; import Template from '../templates/rule/coding-rules-manual-rule-creation.hbs'; import latinize from '../../../helpers/latinize'; +import { translate } from '../../../helpers/l10n'; export default ModalFormView.extend({ template: Template, @@ -118,7 +119,7 @@ export default ModalFormView.extend({ }).fail(function (jqXHR) { if (jqXHR.status === 409) { that.existingRule = jqXHR.responseJSON.rule; - that.showErrors([], [{ msg: window.t('coding_rules.reactivate.help') }]); + that.showErrors([], [{ msg: translate('coding_rules.reactivate.help') }]); that.ui.manualRuleCreationCreate.addClass('hidden'); that.ui.manualRuleCreationReactivate.removeClass('hidden'); } else { diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js index 0d6570dd997..91f93acb4e5 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-description-view.js @@ -22,6 +22,7 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import Template from '../templates/rule/coding-rules-rule-description.hbs'; import confirmDialog from '../confirm-dialog'; +import { translate } from '../../../helpers/l10n'; export default Marionette.ItemView.extend({ template: Template, @@ -83,7 +84,7 @@ export default Marionette.ItemView.extend({ removeExtendedDescription: function () { var that = this; confirmDialog({ - html: window.t('coding_rules.remove_extended_description.confirm'), + html: translate('coding_rules.remove_extended_description.confirm'), yesHandler: function () { that.ui.extendDescriptionText.val(''); that.submitExtendDescription(); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js index 262569496a0..98fabf7f8d4 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js @@ -24,6 +24,7 @@ import Marionette from 'backbone.marionette'; import ProfileActivationView from './profile-activation-view'; import Template from '../templates/rule/coding-rules-rule-profile.hbs'; import confirmDialog from '../confirm-dialog'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default Marionette.ItemView.extend({ tagName: 'tr', @@ -69,8 +70,8 @@ export default Marionette.ItemView.extend({ var that = this, ruleKey = this.options.rule.get('key'); confirmDialog({ - title: window.t('coding_rules.revert_to_parent_definition'), - html: window.tp('coding_rules.revert_to_parent_definition.confirm', this.getParent().name), + title: translate('coding_rules.revert_to_parent_definition'), + html: translateWithParameters('coding_rules.revert_to_parent_definition.confirm', this.getParent().name), yesHandler: function () { return $.ajax({ type: 'POST', @@ -91,8 +92,8 @@ export default Marionette.ItemView.extend({ var that = this, ruleKey = this.options.rule.get('key'); confirmDialog({ - title: window.t('coding_rules.deactivate'), - html: window.tp('coding_rules.deactivate.confirm'), + title: translate('coding_rules.deactivate'), + html: translateWithParameters('coding_rules.deactivate.confirm'), yesHandler: function () { return $.ajax({ type: 'POST', diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js index 20bcfea8d78..f9c33a1ae3b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-empty-view.js @@ -18,11 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import Marionette from 'backbone.marionette'; +import { translate } from '../../helpers/l10n'; export default Marionette.ItemView.extend({ className: 'search-navigator-no-results', template: function () { - return window.t('coding_rules.no_results'); + return translate('coding_rules.no_results'); } }); diff --git a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js index e866ee50cf5..3d9d7b6f08b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js +++ b/server/sonar-web/src/main/js/apps/coding-rules/workspace-list-item-view.js @@ -25,6 +25,7 @@ import ProfileActivationView from './rule/profile-activation-view'; import RuleFilterMixin from './rule/rule-filter-mixin'; import Template from './templates/coding-rules-workspace-list-item.hbs'; import confirmDialog from './confirm-dialog'; +import { translate, translateWithParameters } from '../../helpers/l10n'; export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ className: 'coding-rule', @@ -81,8 +82,8 @@ export default WorkspaceListItemView.extend(RuleFilterMixin).extend({ ruleKey = this.model.get('key'), activation = this.model.get('activation'); confirmDialog({ - title: window.t('coding_rules.deactivate'), - html: window.tp('coding_rules.deactivate.confirm'), + title: translate('coding_rules.deactivate'), + html: translateWithParameters('coding_rules.deactivate.confirm'), yesHandler: function () { return $.ajax({ type: 'POST', diff --git a/server/sonar-web/src/main/js/apps/global-permissions/main.js b/server/sonar-web/src/main/js/apps/global-permissions/main.js index 361a3aab7e4..ea6fdb805c6 100644 --- a/server/sonar-web/src/main/js/apps/global-permissions/main.js +++ b/server/sonar-web/src/main/js/apps/global-permissions/main.js @@ -20,6 +20,7 @@ import $ from 'jquery'; import React from 'react'; import PermissionsList from './permissions-list'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ getInitialState() { @@ -48,9 +49,9 @@ export default React.createClass({ return ( <div className="page"> <header id="global-permissions-header" className="page-header"> - <h1 className="page-title">{window.t('global_permissions.page')}</h1> + <h1 className="page-title">{translate('global_permissions.page')}</h1> {this.renderSpinner()} - <p className="page-description">{window.t('global_permissions.page.description')}</p> + <p className="page-description">{translate('global_permissions.page.description')}</p> </header> <PermissionsList ready={this.state.ready} permissions={this.state.permissions}/> </div> diff --git a/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js index fc4c2f182ae..4d72395a6d2 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/author-facet.js @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import CustomValuesFacet from './custom-values-facet'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ getUrl: function () { @@ -30,13 +31,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return window.t('select2.noMatches'); + return translate('select2.noMatches'); }, formatSearching: function () { - return window.t('select2.searching'); + return translate('select2.searching'); }, formatInputTooShort: function () { - return window.tp('select2.tooShort', 2); + return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: { diff --git a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js index 11d7336b17c..ccf6ce0f8c4 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/custom-values-facet.js @@ -20,6 +20,7 @@ import _ from 'underscore'; import BaseFacet from './base-facet'; import Template from '../templates/facets/issues-custom-values-facet.hbs'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default BaseFacet.extend({ template: Template, @@ -45,13 +46,13 @@ export default BaseFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return window.t('select2.noMatches'); + return translate('select2.noMatches'); }, formatSearching: function () { - return window.t('select2.searching'); + return translate('select2.searching'); }, formatInputTooShort: function () { - return window.tp('select2.tooShort', 2); + return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: this.prepareAjaxSearch() diff --git a/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js index 2343860a363..e1c997ff298 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/language-facet.js @@ -19,6 +19,7 @@ */ import _ from 'underscore'; import CustomValuesFacet from './custom-values-facet'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ getUrl: function () { @@ -31,13 +32,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return window.t('select2.noMatches'); + return translate('select2.noMatches'); }, formatSearching: function () { - return window.t('select2.searching'); + return translate('select2.searching'); }, formatInputTooShort: function () { - return window.tp('select2.tooShort', 2); + return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: { diff --git a/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js index a1a462a0f14..cf274a18c5a 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/project-facet.js @@ -19,6 +19,7 @@ */ import _ from 'underscore'; import CustomValuesFacet from './custom-values-facet'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ @@ -47,13 +48,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return window.t('select2.noMatches'); + return translate('select2.noMatches'); }, formatSearching: function () { - return window.t('select2.searching'); + return translate('select2.searching'); }, formatInputTooShort: function () { - return window.tp('select2.tooShort', 2); + return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: { diff --git a/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js index 24f0494b60b..19458e42da5 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/rule-facet.js @@ -19,6 +19,7 @@ */ import _ from 'underscore'; import CustomValuesFacet from './custom-values-facet'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ prepareSearch: function () { @@ -32,13 +33,13 @@ export default CustomValuesFacet.extend({ minimumInputLength: 2, allowClear: false, formatNoMatches: function () { - return window.t('select2.noMatches'); + return translate('select2.noMatches'); }, formatSearching: function () { - return window.t('select2.searching'); + return translate('select2.searching'); }, formatInputTooShort: function () { - return window.tp('select2.tooShort', 2); + return translateWithParameters('select2.tooShort', 2); }, width: '100%', ajax: { @@ -50,7 +51,7 @@ export default CustomValuesFacet.extend({ results: function (data) { var results; results = data.rules.map(function (rule) { - var lang = rule.langName || window.t('manual'); + var lang = rule.langName || translate('manual'); return { id: rule.key, text: '(' + lang + ') ' + rule.name diff --git a/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js b/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js index 788b885cbf4..1b965c202a8 100644 --- a/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js +++ b/server/sonar-web/src/main/js/apps/issues/facets/tag-facet.js @@ -19,6 +19,7 @@ */ import _ from 'underscore'; import CustomValuesFacet from './custom-values-facet'; +import { translate } from '../../../helpers/l10n'; export default CustomValuesFacet.extend({ prepareSearch: function () { @@ -32,10 +33,10 @@ export default CustomValuesFacet.extend({ minimumInputLength: 0, allowClear: false, formatNoMatches: function () { - return window.t('select2.noMatches'); + return translate('select2.noMatches'); }, formatSearching: function () { - return window.t('select2.searching'); + return translate('select2.searching'); }, width: '100%', ajax: { diff --git a/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js b/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js index 66023267694..edbb3750e25 100644 --- a/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js +++ b/server/sonar-web/src/main/js/apps/issues/workspace-list-empty-view.js @@ -18,11 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import Marionette from 'backbone.marionette'; +import { translate } from '../../helpers/l10n'; export default Marionette.ItemView.extend({ className: 'search-navigator-no-results', template: function () { - return window.t('issue_filter.no_issues'); + return translate('issue_filter.no_issues'); } }); diff --git a/server/sonar-web/src/main/js/apps/overview/components/complexity-distribution.js b/server/sonar-web/src/main/js/apps/overview/components/complexity-distribution.js index 17f375ae0e7..30a02c32db1 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/complexity-distribution.js +++ b/server/sonar-web/src/main/js/apps/overview/components/complexity-distribution.js @@ -21,6 +21,7 @@ import React from 'react'; import { BarChart } from '../../../components/charts/bar-chart'; import { formatMeasure } from '../../../helpers/measures'; +import { translateWithParameters } from '../../../helpers/l10n'; const HEIGHT = 80; @@ -41,7 +42,7 @@ export const ComplexityDistribution = React.createClass({ x: index, y: y, value: value, - tooltip: window.tp(`overview.complexity_tooltip.${this.props.of}`, y, value) + tooltip: translateWithParameters(`overview.complexity_tooltip.${this.props.of}`, y, value) }; }); diff --git a/server/sonar-web/src/main/js/apps/overview/components/coverage-measures.js b/server/sonar-web/src/main/js/apps/overview/components/coverage-measures.js index e557d5cf727..3e50df5ac79 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/coverage-measures.js +++ b/server/sonar-web/src/main/js/apps/overview/components/coverage-measures.js @@ -23,6 +23,7 @@ import { DetailedMeasure } from './detailed-measure'; import { DonutChart } from '../../../components/charts/donut-chart'; import { DrilldownLink } from '../../../components/shared/drilldown-link'; import { formatMeasure, formatMeasureVariation } from '../../../helpers/measures'; +import { translate } from '../../../helpers/l10n'; export const CoverageMeasures = React.createClass({ @@ -84,7 +85,7 @@ export const CoverageMeasures = React.createClass({ return <div className="overview-detailed-measure" style={{ lineHeight: '30px' }}> <div className="overview-detailed-measure-nutshell overview-leak"> <span className="overview-detailed-measure-name"> - {window.t('metric', newCoverageMetricName, 'name')} + {translate('metric', newCoverageMetricName, 'name')} </span> </div> @@ -127,7 +128,7 @@ export const CoverageMeasures = React.createClass({ <div className="overview-detailed-measure" style={{ lineHeight: '30px' }}> <div className="overview-detailed-measure-nutshell"> <span className="overview-detailed-measure-name big"> - {window.t('metric', coverageMetricName, 'name')} + {translate('metric', coverageMetricName, 'name')} </span> <span className="overview-detailed-measure-value"> <span className="spacer-right">{this.renderDonut()}</span> diff --git a/server/sonar-web/src/main/js/apps/overview/components/domain-bubble-chart.js b/server/sonar-web/src/main/js/apps/overview/components/domain-bubble-chart.js index 557103f9a74..62859068807 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/domain-bubble-chart.js +++ b/server/sonar-web/src/main/js/apps/overview/components/domain-bubble-chart.js @@ -21,7 +21,7 @@ import _ from 'underscore'; import React from 'react'; import { BubbleChart } from '../../../components/charts/bubble-chart'; -import { getComponentUrl } from '../../../helpers/urls'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getFiles } from '../../../api/components'; import { formatMeasure } from '../../../helpers/measures'; import Workspace from '../../../components/workspace/main'; @@ -144,10 +144,10 @@ export class DomainBubbleChart extends React.Component { return <div className="overview-domain-chart"> <div className="overview-card-header"> - <h2 className="overview-title">{window.t('overview.chart.files')}</h2> + <h2 className="overview-title">{translate('overview.chart.files')}</h2> <ul className="list-inline small"> <li> - {window.tp('overview.chart.legend.size_x', this.getSizeMetricsTitle())} + {translateWithParameters('overview.chart.legend.size_x', this.getSizeMetricsTitle())} </li> </ul> </div> @@ -160,7 +160,7 @@ export class DomainBubbleChart extends React.Component { {this.state.xMetric.name} </div> {this.state.total > BUBBLES_LIMIT && - <div className="note text-center">{window.tp('overview.chart.files.limit_message', BUBBLES_LIMIT)}</div>} + <div className="note text-center">{translateWithParameters('overview.chart.files.limit_message', BUBBLES_LIMIT)}</div>} </div> </div>; } diff --git a/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js b/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js index ad3898d5e17..40e50720eba 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js +++ b/server/sonar-web/src/main/js/apps/overview/components/domain-timeline.js @@ -27,6 +27,7 @@ import { getEvents } from '../../../api/events'; import { formatMeasure, groupByDomain } from '../../../helpers/measures'; import { getShortType } from '../helpers/metrics'; import { Timeline } from './timeline-chart'; +import { translate } from '../../../helpers/l10n'; const HEIGHT = 280; @@ -244,7 +245,7 @@ export const DomainTimeline = React.createClass({ return <div className="overview-domain-chart"> <div className="overview-card-header"> <div> - <h2 className="overview-title">{window.t('overview.chart.history')}</h2> + <h2 className="overview-title">{translate('overview.chart.history')}</h2> {this.renderTimelineMetricSelect()} </div> {this.renderComparisonMetricSelect()} diff --git a/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js b/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js index ef4eb2f3823..1c39fae9b66 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js +++ b/server/sonar-web/src/main/js/apps/overview/components/domain-treemap.js @@ -24,6 +24,7 @@ import { Treemap } from '../../../components/charts/treemap'; import { getChildren } from '../../../api/components'; import { formatMeasure } from '../../../helpers/measures'; import { getComponentUrl } from '../../../helpers/urls'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; const HEIGHT = 302; @@ -143,13 +144,13 @@ export class DomainTreemap extends React.Component { render () { let color = this.props.colorMetric ? - <li>{window.tp('overview.chart.legend.color_x', this.state.colorMetric.name)}</li> : null; + <li>{translateWithParameters('overview.chart.legend.color_x', this.state.colorMetric.name)}</li> : null; return <div className="overview-domain-chart"> <div className="overview-card-header"> - <h2 className="overview-title">{window.t('overview.chart.components')}</h2> + <h2 className="overview-title">{translate('overview.chart.components')}</h2> <ul className="list-inline small"> <li> - {window.tp('overview.chart.legend.size_x', this.state.sizeMetric.name)} + {translateWithParameters('overview.chart.legend.size_x', this.state.sizeMetric.name)} </li> {color} </ul> diff --git a/server/sonar-web/src/main/js/apps/overview/components/event.js b/server/sonar-web/src/main/js/apps/overview/components/event.js index 26835342ae6..f333643b774 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/event.js +++ b/server/sonar-web/src/main/js/apps/overview/components/event.js @@ -21,6 +21,7 @@ import React from 'react'; import moment from 'moment'; import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; +import { translate } from '../../../helpers/l10n'; export const Event = React.createClass({ @@ -40,7 +41,7 @@ export const Event = React.createClass({ const { event } = this.props; return <li className="spacer-top"> <p> - <strong className="js-event-type">{window.t('event.category', event.type)}</strong> + <strong className="js-event-type">{translate('event.category', event.type)}</strong> : <span className="js-event-name">{event.name}</span> { event.text && <i className="spacer-left icon-help" data-toggle="tooltip" title={event.text}/> } diff --git a/server/sonar-web/src/main/js/apps/overview/components/events-list-filter.js b/server/sonar-web/src/main/js/apps/overview/components/events-list-filter.js index 9e13efd0c74..71b5e927b02 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/events-list-filter.js +++ b/server/sonar-web/src/main/js/apps/overview/components/events-list-filter.js @@ -19,6 +19,7 @@ */ import React from 'react'; import Select from 'react-select'; +import { translate } from '../../../helpers/l10n'; const TYPES = ['All', 'Version', 'Alert', 'Profile', 'Other']; @@ -38,7 +39,7 @@ export const EventsListFilter = React.createClass({ const options = TYPES.map(type => { return { value: type, - label: window.t('event.category', type) + label: translate('event.category', type) }; }); return <Select value={this.props.currentFilter} diff --git a/server/sonar-web/src/main/js/apps/overview/components/events-list.js b/server/sonar-web/src/main/js/apps/overview/components/events-list.js index 8d2f4f1b94a..aef93084cd7 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/events-list.js +++ b/server/sonar-web/src/main/js/apps/overview/components/events-list.js @@ -21,6 +21,7 @@ import React from 'react'; import { Event } from './event'; import { EventsListFilter } from './events-list-filter'; +import { translate } from '../../../helpers/l10n'; const LIMIT = 5; @@ -64,7 +65,7 @@ export const EventsList = React.createClass({ renderMoreLink(filteredEvents) { if (filteredEvents.length > LIMIT) { - const text = this.state.limited ? window.t('widget.events.show_all') : window.t('hide'); + const text = this.state.limited ? translate('widget.events.show_all') : translate('hide'); return <p className="spacer-top note"> <a onClick={this.handleClick} href="#">{text}</a> </p>; @@ -77,7 +78,7 @@ export const EventsList = React.createClass({ if (events.length) { return <ul>{events.map(event => <Event key={event.id} event={event}/>)}</ul>; } else { - return <p className="spacer-top note">{window.t('no_results')}</p>; + return <p className="spacer-top note">{translate('no_results')}</p>; } }, @@ -86,7 +87,7 @@ export const EventsList = React.createClass({ const events = this.limitEvents(filteredEvents); return <div className="overview-meta-card"> <div className="clearfix"> - <h4 className="pull-left overview-meta-header">{window.t('widget.events.name')}</h4> + <h4 className="pull-left overview-meta-header">{translate('widget.events.name')}</h4> <div className="pull-right"> <EventsListFilter currentFilter={this.state.filter} onFilter={this.handleFilter}/> </div> diff --git a/server/sonar-web/src/main/js/apps/overview/components/issue-measure.js b/server/sonar-web/src/main/js/apps/overview/components/issue-measure.js index 7be47e35000..8b6fc0fd9ab 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/issue-measure.js +++ b/server/sonar-web/src/main/js/apps/overview/components/issue-measure.js @@ -25,6 +25,7 @@ import { DrilldownLink } from '../../../components/shared/drilldown-link'; import { IssuesLink } from '../../../components/shared/issues-link'; import { getShortType } from '../helpers/metrics'; import SeverityHelper from '../../../components/shared/severity-helper'; +import { translate } from '../../../helpers/l10n'; export const IssueMeasure = React.createClass({ @@ -91,7 +92,7 @@ export const AddedRemovedMeasure = React.createClass({ return <div className="overview-detailed-measure-leak"> <ul> <li style={{ display: 'flex', alignItems: 'baseline' }}> - <small className="flex-1 text-left">{window.t('overview.added')}</small> + <small className="flex-1 text-left">{translate('overview.added')}</small> <IssuesLink className="text-danger" component={this.props.component.key} params={{ resolved: 'false', createdAfter }}> <span className="overview-detailed-measure-value"> @@ -100,7 +101,7 @@ export const AddedRemovedMeasure = React.createClass({ </IssuesLink> </li> <li className="little-spacer-top" style={{ display: 'flex', alignItems: 'baseline' }}> - <small className="flex-1 text-left">{window.t('overview.removed')}</small> + <small className="flex-1 text-left">{translate('overview.removed')}</small> <span className="text-success"> {formatMeasure(removed, getShortType(this.props.type))} </span> @@ -195,7 +196,7 @@ export const OnNewCodeMeasure = React.createClass({ return <div className="overview-detailed-measure-leak"> <ul> <li className="little-spacer-top" style={{ display: 'flex', alignItems: 'center' }}> - <small className="flex-1 text-left">{window.t('overview.on_new_code')}</small> + <small className="flex-1 text-left">{translate('overview.on_new_code')}</small> <DrilldownLink component={this.props.component.key} metric={this.props.leakMetric} period={this.props.leakPeriodIndex}> <span className="overview-detailed-measure-value"> @@ -253,7 +254,7 @@ export const SeverityMeasure = React.createClass({ return <div className="overview-detailed-measure-leak"> <ul> <li style={{ display: 'flex', alignItems: 'baseline' }}> - <small className="flex-1 text-left text-ellipsis">{window.t('overview.added')}</small> + <small className="flex-1 text-left text-ellipsis">{translate('overview.added')}</small> <IssuesLink className="text-danger" component={this.props.component.key} params={{ resolved: 'false', severities: this.props.severity, createdAfter: createdAfter }}> @@ -263,7 +264,7 @@ export const SeverityMeasure = React.createClass({ </IssuesLink> </li> <li className="little-spacer-top" style={{ display: 'flex', alignItems: 'baseline' }}> - <small className="flex-1 text-left text-ellipsis">{window.t('overview.removed')}</small> + <small className="flex-1 text-left text-ellipsis">{translate('overview.removed')}</small> <span className="text-success"> {formatMeasure(removed, 'SHORT_INT')} </span> diff --git a/server/sonar-web/src/main/js/apps/overview/components/language-distribution.js b/server/sonar-web/src/main/js/apps/overview/components/language-distribution.js index 54023da8416..a41c46961d6 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/language-distribution.js +++ b/server/sonar-web/src/main/js/apps/overview/components/language-distribution.js @@ -23,6 +23,7 @@ import React from 'react'; import { Histogram } from '../../../components/charts/histogram'; import { formatMeasure } from '../../../helpers/measures'; import { getLanguages } from '../../../api/languages'; +import { translate } from '../../../helpers/l10n'; export const LanguageDistribution = React.createClass({ @@ -42,7 +43,7 @@ export const LanguageDistribution = React.createClass({ getLanguageName (langKey) { if (this.state && this.state.languages) { let lang = _.findWhere(this.state.languages, { key: langKey }); - return lang ? lang.name : window.t('unknown'); + return lang ? lang.name : translate('unknown'); } else { return langKey; } diff --git a/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js b/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js index c0ed2396f88..5c616443847 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js +++ b/server/sonar-web/src/main/js/apps/overview/components/ncloc-distribution.js @@ -25,6 +25,7 @@ import { formatMeasure } from '../../../helpers/measures'; import { collapsePath } from '../../../helpers/path'; import { getComponentDrilldownUrl } from '../../../helpers/urls'; import { getChildren } from '../../../api/components'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; const HEIGHT = 302; @@ -105,9 +106,9 @@ export const NclocDistribution = React.createClass({ render () { return <div className="overview-domain-chart"> <div className="overview-card-header"> - <h2 className="overview-title">{window.t('overview.chart.components')}</h2> + <h2 className="overview-title">{translate('overview.chart.components')}</h2> <span className="small"> - {window.tp('overview.chart.legend.size_x', window.t('metric.ncloc.name'))} + {translateWithParameters('overview.chart.legend.size_x', translate('metric.ncloc.name'))} </span> </div> <div className="overview-bar-chart"> diff --git a/server/sonar-web/src/main/js/apps/overview/domains/coverage-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/coverage-domain.js index e5b9eb00c9c..06eda8f2c48 100644 --- a/server/sonar-web/src/main/js/apps/overview/domains/coverage-domain.js +++ b/server/sonar-web/src/main/js/apps/overview/domains/coverage-domain.js @@ -31,6 +31,7 @@ import { filterMetrics, filterMetricsForDomains } from '../helpers/metrics'; import { DomainLeakTitle } from '../main/components'; import { CHART_REVERSED_COLORS_RANGE_PERCENT } from '../../../helpers/constants'; import { CoverageMeasuresList } from '../components/coverage-measures-list'; +import { translate } from '../../../helpers/l10n'; const TEST_DOMAINS = ['Tests', 'Tests (Integration)', 'Tests (Overall)']; @@ -95,7 +96,7 @@ export const CoverageMain = React.createClass({ renderEmpty() { return <div className="overview-detailed-page"> <div className="page"> - <p>{window.t('overview.no_coverage')}</p> + <p>{translate('overview.no_coverage')}</p> </div> </div>; }, @@ -124,7 +125,7 @@ export const CoverageMain = React.createClass({ <div className="overview-cards-list"> <div className="overview-card overview-card-fixed-width"> <div className="overview-card-header"> - <div className="overview-title">{window.t('overview.domain.coverage')}</div> + <div className="overview-title">{translate('overview.domain.coverage')}</div> {this.renderLegend()} </div> <CoverageMeasuresList {...this.props} {...this.state}/> diff --git a/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js index f306070c421..bdbff57b114 100644 --- a/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js +++ b/server/sonar-web/src/main/js/apps/overview/domains/debt-domain.js @@ -40,6 +40,7 @@ import { getFacet, extractAssignees } from '../../../api/issues'; import { Rating } from '../../../components/shared/rating'; import { DrilldownLink } from '../../../components/shared/drilldown-link'; import { DomainLeakTitle } from '../main/components'; +import { translate } from '../../../helpers/l10n'; const KNOWN_METRICS = ['violations', 'sqale_index', 'sqale_rating', 'sqale_debt_ratio', 'blocker_violations', @@ -182,7 +183,7 @@ export const DebtMain = React.createClass({ <div className="overview-cards-list"> <div className="overview-card overview-card-fixed-width"> <div className="overview-card-header"> - <div className="overview-title">{window.t('overview.domain.debt')}</div> + <div className="overview-title">{translate('overview.domain.debt')}</div> {this.renderLegend()} </div> @@ -209,7 +210,7 @@ export const DebtMain = React.createClass({ <div className="overview-detailed-measure"> <div className="overview-detailed-measure-nutshell"> <div className="overview-detailed-measure-name"> - {window.t('overview.unmanaged_issues')} + {translate('overview.unmanaged_issues')} </div> <div className="spacer-top"> <Assignees {...this.props} assignees={this.state.assignees}/> diff --git a/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js index c048100cc51..ab91ef521b5 100644 --- a/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js +++ b/server/sonar-web/src/main/js/apps/overview/domains/duplications-domain.js @@ -33,6 +33,7 @@ import { CHART_COLORS_RANGE_PERCENT } from '../../../helpers/constants'; import { formatMeasure, formatMeasureVariation } from '../../../helpers/measures'; import { DonutChart } from '../../../components/charts/donut-chart'; import { DrilldownLink } from '../../../components/shared/drilldown-link'; +import { translate } from '../../../helpers/l10n'; export const DuplicationsMain = React.createClass({ @@ -89,7 +90,7 @@ export const DuplicationsMain = React.createClass({ renderEmpty() { return <div className="overview-detailed-page"> <div className="page"> - <p>{window.t('overview.no_duplications')}</p> + <p>{translate('overview.no_duplications')}</p> </div> </div>; }, @@ -157,7 +158,7 @@ export const DuplicationsMain = React.createClass({ <div className="overview-cards-list"> <div className="overview-card overview-card-fixed-width"> <div className="overview-card-header"> - <div className="overview-title">{window.t('overview.domain.duplications')}</div> + <div className="overview-title">{translate('overview.domain.duplications')}</div> {this.renderLegend()} </div> <div className="overview-detailed-measures-list"> diff --git a/server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js b/server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js index a57eeca5c25..c1199d9732c 100644 --- a/server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js +++ b/server/sonar-web/src/main/js/apps/overview/domains/structure-domain.js @@ -29,6 +29,7 @@ import { getPeriodLabel, getPeriodDate } from './../helpers/periods'; import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; import { filterMetrics, filterMetricsForDomains } from '../helpers/metrics'; import { DomainLeakTitle } from '../main/components'; +import { translate } from '../../../helpers/l10n'; export const StructureMain = React.createClass({ @@ -168,7 +169,7 @@ export const StructureMain = React.createClass({ return <div className="overview-detailed-page"> <div className="overview-card"> <div className="overview-card-header"> - <div className="overview-title">{window.t('overview.domain.structure')}</div> + <div className="overview-title">{translate('overview.domain.structure')}</div> {this.renderLegend()} </div> diff --git a/server/sonar-web/src/main/js/apps/overview/gate/gate-condition.js b/server/sonar-web/src/main/js/apps/overview/gate/gate-condition.js index f237ba4eff5..bed48f92f7e 100644 --- a/server/sonar-web/src/main/js/apps/overview/gate/gate-condition.js +++ b/server/sonar-web/src/main/js/apps/overview/gate/gate-condition.js @@ -22,6 +22,7 @@ import React from 'react'; import { getPeriodLabel, getPeriodDate } from '../helpers/periods'; import { DrilldownLink } from '../../../components/shared/drilldown-link'; import { formatMeasure } from '../../../helpers/measures'; +import { translate } from '../../../helpers/l10n'; const Measure = React.createClass({ @@ -37,7 +38,7 @@ const Measure = React.createClass({ export default React.createClass({ render() { - let metricName = window.t('metric', this.props.condition.metric.name, 'name'); + let metricName = translate('metric', this.props.condition.metric.name, 'name'); let threshold = this.props.condition.level === 'ERROR' ? this.props.condition.error : this.props.condition.warning; let period = this.props.condition.period ? @@ -63,7 +64,7 @@ export default React.createClass({ <div className="overview-gate-condition-metric"> <div>{metricName}</div> <div> - {window.t('quality_gates.operator', this.props.condition.op, 'short')} + {translate('quality_gates.operator', this.props.condition.op, 'short')} {' '} <Measure value={threshold} type={this.props.condition.metric.type}/> </div> diff --git a/server/sonar-web/src/main/js/apps/overview/gate/gate-empty.js b/server/sonar-web/src/main/js/apps/overview/gate/gate-empty.js index a915ea17f9b..30368e463f0 100644 --- a/server/sonar-web/src/main/js/apps/overview/gate/gate-empty.js +++ b/server/sonar-web/src/main/js/apps/overview/gate/gate-empty.js @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; +import { translate } from '../../../helpers/l10n'; export default React.createClass({ render() { @@ -25,7 +26,7 @@ export default React.createClass({ return ( <div className="overview-gate"> - <h2 className="overview-title">{window.t('overview.quality_gate')}</h2> + <h2 className="overview-title">{translate('overview.quality_gate')}</h2> <p className="overview-gate-warning"> You should <a href={qualityGatesUrl}>define</a> a quality gate on this project.</p> </div> diff --git a/server/sonar-web/src/main/js/apps/overview/gate/gate.js b/server/sonar-web/src/main/js/apps/overview/gate/gate.js index 28e6bc23e19..01830260759 100644 --- a/server/sonar-web/src/main/js/apps/overview/gate/gate.js +++ b/server/sonar-web/src/main/js/apps/overview/gate/gate.js @@ -21,6 +21,7 @@ import React from 'react'; import GateConditions from './gate-conditions'; import GateEmpty from './gate-empty'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default React.createClass({ @@ -31,11 +32,11 @@ export default React.createClass({ renderGateText () { let text = ''; if (this.props.gate.level === 'ERROR') { - text = window.tp('overview.gate.view.errors', this.props.gate.text); + text = translateWithParameters('overview.gate.view.errors', this.props.gate.text); } else if (this.props.gate.level === 'WARN') { - text = window.tp('overview.gate.view.warnings', this.props.gate.text); + text = translateWithParameters('overview.gate.view.warnings', this.props.gate.text); } else { - text = window.t('overview.gate.view.no_alert'); + text = translate('overview.gate.view.no_alert'); } return <div className="overview-card">{text}</div>; }, @@ -47,12 +48,12 @@ export default React.createClass({ let level = this.props.gate.level.toLowerCase(); let badgeClassName = 'badge badge-' + level; - let badgeText = window.t('overview.gate', this.props.gate.level); + let badgeText = translate('overview.gate', this.props.gate.level); return ( <div className="overview-gate"> <h2 className="overview-title"> - {window.t('overview.quality_gate')} + {translate('overview.quality_gate')} <span className={badgeClassName}>{badgeText}</span> </h2> {this.props.gate.conditions ? this.renderGateConditions() : this.renderGateText()} diff --git a/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js b/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js index f1c4ea34522..c224dfcd3af 100644 --- a/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js +++ b/server/sonar-web/src/main/js/apps/overview/helpers/metrics.js @@ -17,6 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { translate } from '../../../helpers/l10n'; + function hasRightDomain (metric, domains) { return domains.indexOf(metric.domain) !== -1; } @@ -55,5 +57,5 @@ export function getShortType (type) { export function getMetricName (metricKey) { - return window.t('overview.metric', metricKey); + return translate('overview.metric', metricKey); } diff --git a/server/sonar-web/src/main/js/apps/overview/helpers/periods.js b/server/sonar-web/src/main/js/apps/overview/helpers/periods.js index 4542500f319..8458eb1298a 100644 --- a/server/sonar-web/src/main/js/apps/overview/helpers/periods.js +++ b/server/sonar-web/src/main/js/apps/overview/helpers/periods.js @@ -19,6 +19,7 @@ */ import _ from 'underscore'; import moment from 'moment'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export function getPeriodLabel (periods, periodIndex) { @@ -27,9 +28,9 @@ export function getPeriodLabel (periods, periodIndex) { return null; } if (period.mode === 'previous_version' && !period.modeParam) { - return window.t('overview.period.previous_version_only_date'); + return translate('overview.period.previous_version_only_date'); } - return window.tp(`overview.period.${period.mode}`, period.modeParam); + return translateWithParameters(`overview.period.${period.mode}`, period.modeParam); } diff --git a/server/sonar-web/src/main/js/apps/overview/main/components.js b/server/sonar-web/src/main/js/apps/overview/main/components.js index e5c7c37ef8b..fe4b6ca2fd6 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/components.js +++ b/server/sonar-web/src/main/js/apps/overview/main/components.js @@ -21,6 +21,7 @@ import moment from 'moment'; import React from 'react'; import { Timeline } from './timeline'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export const Domain = React.createClass({ @@ -39,7 +40,7 @@ export const DomainTitle = React.createClass({ <div className="overview-title"> {this.props.children} <a className="small big-spacer-left link-no-underline" href={url}> - {window.t('more')} + {translate('more')} <i className="icon-chevron-right" style={{ position: 'relative', top: -1 }}/> </a> </div> @@ -54,8 +55,8 @@ export const DomainTitle = React.createClass({ export const DomainLeakTitle = React.createClass({ renderInline (tooltip, fromNow) { return <span className="overview-domain-leak-title" title={tooltip} data-toggle="tooltip"> - <span>{window.tp('overview.leak_period_x', this.props.label)}</span> - <span className="note spacer-left">{window.tp('overview.started_x', fromNow)}</span> + <span>{translateWithParameters('overview.leak_period_x', this.props.label)}</span> + <span className="note spacer-left">{translateWithParameters('overview.started_x', fromNow)}</span> </span>; }, @@ -70,9 +71,9 @@ export const DomainLeakTitle = React.createClass({ return this.renderInline(tooltip, fromNow); } return <span className="overview-domain-leak-title" title={tooltip} data-toggle="tooltip"> - <span>{window.tp('overview.leak_period_x', this.props.label)}</span> + <span>{translateWithParameters('overview.leak_period_x', this.props.label)}</span> <br/> - <span className="note">{window.tp('overview.started_x', fromNow)}</span> + <span className="note">{translateWithParameters('overview.started_x', fromNow)}</span> </span>; } }); @@ -158,7 +159,11 @@ export const DomainMixin = { renderTimelineStartDate() { let momentDate = moment(this.props.historyStartDate); let fromNow = momentDate.fromNow(); - return <span className="overview-domain-timeline-date">{window.tp('overview.started_x', fromNow)}</span>; + return ( + <span className="overview-domain-timeline-date"> + {translateWithParameters('overview.started_x', fromNow)} + </span> + ); }, renderTimeline(range, displayDate) { diff --git a/server/sonar-web/src/main/js/apps/overview/main/coverage.js b/server/sonar-web/src/main/js/apps/overview/main/coverage.js index 3b6357d1213..1e113516c2c 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/coverage.js +++ b/server/sonar-web/src/main/js/apps/overview/main/coverage.js @@ -32,6 +32,7 @@ import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; import { DonutChart } from '../../../components/charts/donut-chart'; import { getMetricName } from '../helpers/metrics'; import { formatMeasure } from '../../../helpers/measures'; +import { translate } from '../../../helpers/l10n'; export const GeneralCoverage = React.createClass({ @@ -105,7 +106,7 @@ export const GeneralCoverage = React.createClass({ return <Domain> <DomainHeader component={this.props.component} - title={window.t('overview.domain.coverage')} + title={translate('overview.domain.coverage')} linkTo="/coverage"/> <DomainPanel> diff --git a/server/sonar-web/src/main/js/apps/overview/main/debt.js b/server/sonar-web/src/main/js/apps/overview/main/debt.js index 411befd414a..47034a6f6c8 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/debt.js +++ b/server/sonar-web/src/main/js/apps/overview/main/debt.js @@ -35,6 +35,7 @@ import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; import { Legend } from '../components/legend'; import { getMetricName } from '../helpers/metrics'; import { formatMeasure } from '../../../helpers/measures'; +import { translate } from '../../../helpers/l10n'; export const GeneralDebt = React.createClass({ @@ -76,7 +77,7 @@ export const GeneralDebt = React.createClass({ render () { return <Domain> <DomainHeader component={this.props.component} - title={window.t('overview.domain.debt')} + title={translate('overview.domain.debt')} linkTo="/debt"/> <DomainPanel> diff --git a/server/sonar-web/src/main/js/apps/overview/main/duplications.js b/server/sonar-web/src/main/js/apps/overview/main/duplications.js index f6869971b7e..857c32ca55e 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/duplications.js +++ b/server/sonar-web/src/main/js/apps/overview/main/duplications.js @@ -32,6 +32,7 @@ import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; import { DonutChart } from '../../../components/charts/donut-chart'; import { getMetricName } from '../helpers/metrics'; import { formatMeasure, formatMeasureVariation } from '../../../helpers/measures'; +import { translate } from '../../../helpers/l10n'; export const GeneralDuplications = React.createClass({ @@ -77,7 +78,7 @@ export const GeneralDuplications = React.createClass({ return <Domain> <DomainHeader component={this.props.component} - title={window.t('overview.domain.duplications')} + title={translate('overview.domain.duplications')} linkTo="/duplications"/> <DomainPanel> diff --git a/server/sonar-web/src/main/js/apps/overview/main/structure.js b/server/sonar-web/src/main/js/apps/overview/main/structure.js index d06d14af65c..12a93592b95 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/structure.js +++ b/server/sonar-web/src/main/js/apps/overview/main/structure.js @@ -32,6 +32,7 @@ import { TooltipsMixin } from '../../../components/mixins/tooltips-mixin'; import { getMetricName } from '../helpers/metrics'; import { formatMeasure, formatMeasureVariation } from '../../../helpers/measures'; import { LanguageDistribution } from '../components/language-distribution'; +import { translate } from '../../../helpers/l10n'; export const GeneralStructure = React.createClass({ @@ -71,7 +72,7 @@ export const GeneralStructure = React.createClass({ render () { return <Domain> <DomainHeader component={this.props.component} - title={window.t('overview.domain.structure')} + title={translate('overview.domain.structure')} linkTo="/structure"/> <DomainPanel> diff --git a/server/sonar-web/src/main/js/apps/overview/meta.js b/server/sonar-web/src/main/js/apps/overview/meta.js index 5a9a44f84ac..3506f29c1ad 100644 --- a/server/sonar-web/src/main/js/apps/overview/meta.js +++ b/server/sonar-web/src/main/js/apps/overview/meta.js @@ -25,6 +25,7 @@ import { QualityProfileLink } from './../../components/shared/quality-profile-li import { QualityGateLink } from './../../components/shared/quality-gate-link'; import { getEvents } from '../../api/events'; import { EventsList } from './components/events-list'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ @@ -96,14 +97,14 @@ export default React.createClass({ let profilesCard = !this.isView() && !this.isDeveloper() && _.size(this.props.component.profiles) > 0 ? ( <div className="overview-meta-card"> - <h4 className="overview-meta-header">{window.t('overview.quality_profiles')}</h4> + <h4 className="overview-meta-header">{translate('overview.quality_profiles')}</h4> <ul className="overview-meta-list">{profiles}</ul> </div> ) : null; let gateCard = !this.isView() && !this.isDeveloper() && this.props.component.gate ? ( <div className="overview-meta-card"> - <h4 className="overview-meta-header">{window.t('overview.quality_gate')}</h4> + <h4 className="overview-meta-header">{translate('overview.quality_gate')}</h4> <ul className="overview-meta-list"> <li> {this.props.component.gate.isDefault ? diff --git a/server/sonar-web/src/main/js/apps/overview/overview.js b/server/sonar-web/src/main/js/apps/overview/overview.js index ca7e46e117f..d9ff5e64543 100644 --- a/server/sonar-web/src/main/js/apps/overview/overview.js +++ b/server/sonar-web/src/main/js/apps/overview/overview.js @@ -29,6 +29,7 @@ import { DebtMain } from './domains/debt-domain'; import { getMetrics } from '../../api/metrics'; import { RouterMixin } from '../../components/router/router'; +import { translate } from '../../helpers/l10n'; export const Overview = React.createClass({ @@ -113,7 +114,7 @@ export const EmptyOverview = React.createClass({ return ( <div className="page"> <div className="alert alert-warning"> - {window.t('provisioning.no_analysis')} + {translate('provisioning.no_analysis')} </div> </div> ); diff --git a/server/sonar-web/src/main/js/apps/permission-templates/header.js b/server/sonar-web/src/main/js/apps/permission-templates/header.js index fd496137ba3..95c653fa0b5 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/header.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/header.js @@ -19,6 +19,7 @@ */ import React from 'react'; import CreateView from './create-view'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ onCreate(e) { @@ -38,12 +39,12 @@ export default React.createClass({ render() { return ( <header id="project-permissions-header" className="page-header"> - <h1 className="page-title">{window.t('permission_templates.page')}</h1> + <h1 className="page-title">{translate('permission_templates.page')}</h1> {this.renderSpinner()} <div className="page-actions"> <button onClick={this.onCreate}>Create</button> </div> - <p className="page-description">{window.t('roles.page.description')}</p> + <p className="page-description">{translate('roles.page.description')}</p> </header> ); } diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.js b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.js index 81768d78af1..c3b14929147 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-defaults.js @@ -20,6 +20,7 @@ import _ from 'underscore'; import React from 'react'; import QualifierIcon from '../../components/shared/qualifier-icon'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ propTypes: { @@ -37,7 +38,7 @@ export default React.createClass({ renderIfMultipleTopQualifiers() { let defaults = this.props.permissionTemplate.defaultFor.map(qualifier => { - return <li key={qualifier}><QualifierIcon qualifier={qualifier}/> {window.t('qualifier', qualifier)}</li>; + return <li key={qualifier}><QualifierIcon qualifier={qualifier}/> {translate('qualifier', qualifier)}</li>; }); return ( <ul className="list-inline nowrap spacer-bottom"> diff --git a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.js b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.js index b785faf7c64..fdfaf924beb 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/permission-template-set-defaults.js @@ -21,6 +21,7 @@ import _ from 'underscore'; import React from 'react'; import { setDefaultPermissionTemplate } from '../../api/permissions'; import QualifierIcon from '../../components/shared/qualifier-icon'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ propTypes: { @@ -55,7 +56,7 @@ export default React.createClass({ return ( <li key={qualifier}> <a onClick={this.setDefault.bind(this, qualifier)} href="#"> - Set Default for <QualifierIcon qualifier={qualifier}/> {window.t('qualifier', qualifier)} + Set Default for <QualifierIcon qualifier={qualifier}/> {translate('qualifier', qualifier)} </a> </li> ); diff --git a/server/sonar-web/src/main/js/apps/project-permissions/main.js b/server/sonar-web/src/main/js/apps/project-permissions/main.js index 033f6a13f2d..7028384ff6a 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/main.js +++ b/server/sonar-web/src/main/js/apps/project-permissions/main.js @@ -25,6 +25,7 @@ import Permissions from './permissions'; import PermissionsFooter from './permissions-footer'; import Search from './search'; import ApplyTemplateView from './apply-template-view'; +import { translate } from '../../helpers/l10n'; const PERMISSIONS_ORDER = ['user', 'codeviewer', 'issueadmin', 'admin']; @@ -132,12 +133,12 @@ export default React.createClass({ return ( <div className="page"> <header id="project-permissions-header" className="page-header"> - <h1 className="page-title">{window.t('roles.page')}</h1> + <h1 className="page-title">{translate('roles.page')}</h1> {this.renderSpinner()} <div className="page-actions"> {this.renderBulkApplyButton()} </div> - <p className="page-description">{window.t('roles.page.description2')}</p> + <p className="page-description">{translate('roles.page.description2')}</p> </header> <Search {...this.props} diff --git a/server/sonar-web/src/main/js/apps/project-permissions/qualifier-filter.js b/server/sonar-web/src/main/js/apps/project-permissions/qualifier-filter.js index 563f6a2b9e0..e514803c0ca 100644 --- a/server/sonar-web/src/main/js/apps/project-permissions/qualifier-filter.js +++ b/server/sonar-web/src/main/js/apps/project-permissions/qualifier-filter.js @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; +import { translate } from '../../helpers/l10n'; import RadioToggle from '../../components/shared/radio-toggle'; @@ -26,7 +27,7 @@ const rootQualifiersToOptions = (qualifiers) => { return qualifiers.map(q => { return { value: q, - label: window.t('qualifiers', q) + label: translate('qualifiers', q) }; }); }; diff --git a/server/sonar-web/src/main/js/apps/projects/search.js b/server/sonar-web/src/main/js/apps/projects/search.js index 4b17fd2b804..ba94920a966 100644 --- a/server/sonar-web/src/main/js/apps/projects/search.js +++ b/server/sonar-web/src/main/js/apps/projects/search.js @@ -23,6 +23,7 @@ import { TYPE, QUALIFIERS_ORDER } from './constants'; import DeleteView from './delete-view'; import RadioToggle from '../../components/shared/radio-toggle'; import Checkbox from '../../components/shared/checkbox'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ propTypes: { @@ -49,7 +50,7 @@ export default React.createClass({ getQualifierOptions() { let options = this.props.topLevelQualifiers.map(q => { - return { value: q, label: window.t('qualifiers', q) }; + return { value: q, label: translate('qualifiers', q) }; }); return _.sortBy(options, option => { return QUALIFIERS_ORDER.indexOf(option.value); @@ -82,7 +83,7 @@ export default React.createClass({ if (this.props.type !== TYPE.GHOSTS || !this.props.ready) { return null; } - return <div className="spacer-top alert alert-info">{window.t('bulk_deletion.ghosts.description')}</div>; + return <div className="spacer-top alert alert-info">{translate('bulk_deletion.ghosts.description')}</div>; }, deleteProjects() { diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js index d20325015b8..3b377dc0afd 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-condition-view.js @@ -21,6 +21,7 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import DeleteConditionView from './gate-conditions-delete-view'; import Template from './templates/quality-gate-detail-condition.hbs'; +import { translate } from '../../helpers/l10n'; export default Marionette.ItemView.extend({ tagName: 'tr', @@ -109,7 +110,7 @@ export default Marionette.ItemView.extend({ return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), { canEdit: this.options.canEdit, periods: this.options.periods, - periodText: period ? period.text : window.t('value'), + periodText: period ? period.text : translate('value'), metric: this.getMetric(), isDiffMetric: this.isDiffMetric() }); diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js index 542c6ce5f24..b159e42fb2e 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-conditions-view.js @@ -23,6 +23,7 @@ import Condition from './condition'; import ConditionView from './gate-condition-view'; import ConditionsEmptyView from './gate-conditions-empty-view'; import Template from './templates/quality-gate-detail-conditions.hbs'; +import { translate } from '../../helpers/l10n'; export default Marionette.CompositeView.extend({ template: Template, @@ -53,7 +54,7 @@ export default Marionette.CompositeView.extend({ this.ui.metricSelect.select2({ allowClear: false, width: '250px', - placeholder: window.t('alerts.select_metric') + placeholder: translate('alerts.select_metric') }); }, diff --git a/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js b/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js index 7c1d884b4a7..3a655d32778 100644 --- a/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js +++ b/server/sonar-web/src/main/js/apps/quality-gates/gate-projects-view.js @@ -21,6 +21,7 @@ import _ from 'underscore'; import Marionette from 'backbone.marionette'; import Template from './templates/quality-gate-detail-projects.hbs'; import '../../components/common/select-list'; +import { translate } from '../../helpers/l10n'; export default Marionette.ItemView.extend({ template: Template, @@ -44,14 +45,14 @@ export default Marionette.ItemView.extend({ selectParameter: 'projectId', selectParameterValue: 'id', labels: { - selected: window.t('quality_gates.projects.with'), - deselected: window.t('quality_gates.projects.without'), - all: window.t('quality_gates.projects.all'), - noResults: window.t('quality_gates.projects.noResults') + selected: translate('quality_gates.projects.with'), + deselected: translate('quality_gates.projects.without'), + all: translate('quality_gates.projects.all'), + noResults: translate('quality_gates.projects.noResults') }, tooltips: { - select: window.t('quality_gates.projects.select_hint'), - deselect: window.t('quality_gates.projects.deselect_hint') + select: translate('quality_gates.projects.select_hint'), + deselect: translate('quality_gates.projects.deselect_hint') } }); } diff --git a/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js b/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js index a8b903dd562..0f8e9bbb1c7 100644 --- a/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js +++ b/server/sonar-web/src/main/js/apps/quality-profiles/profile-details-view.js @@ -25,6 +25,7 @@ import ProfileChangelogView from './profile-changelog-view'; import ProfileComparisonView from './profile-comparison-view'; import '../../components/common/select-list'; import Template from './templates/quality-profiles-profile-details.hbs'; +import { translate } from '../../helpers/l10n'; export default Marionette.LayoutView.extend({ template: Template, @@ -92,14 +93,14 @@ export default Marionette.LayoutView.extend({ selectParameter: 'projectUuid', selectParameterValue: 'uuid', labels: { - selected: window.t('quality_gates.projects.with'), - deselected: window.t('quality_gates.projects.without'), - all: window.t('quality_gates.projects.all'), - noResults: window.t('quality_gates.projects.noResults') + selected: translate('quality_gates.projects.with'), + deselected: translate('quality_gates.projects.without'), + all: translate('quality_gates.projects.all'), + noResults: translate('quality_gates.projects.noResults') }, tooltips: { - select: window.t('quality_profiles.projects.select_hint'), - deselect: window.t('quality_profiles.projects.deselect_hint') + select: translate('quality_profiles.projects.select_hint'), + deselect: translate('quality_profiles.projects.deselect_hint') } }); this.listenTo(this.projectsSelectList.collection, 'change:selected', this.onProjectsChange); diff --git a/server/sonar-web/src/main/js/apps/system/item-log-level.js b/server/sonar-web/src/main/js/apps/system/item-log-level.js index e832bd086eb..e6977c40d5b 100644 --- a/server/sonar-web/src/main/js/apps/system/item-log-level.js +++ b/server/sonar-web/src/main/js/apps/system/item-log-level.js @@ -19,6 +19,7 @@ */ import React from 'react'; import { setLogLevel } from '../../api/system'; +import { translate } from '../../helpers/l10n'; const LOG_LEVELS = ['INFO', 'DEBUG', 'TRACE']; @@ -40,7 +41,7 @@ export default React.createClass({ }); let warning = this.state.level !== 'INFO' ? ( <div className="alert alert-danger spacer-top" style={{ wordBreak: 'normal' }}> - {window.t('system.log_level.warning')} + {translate('system.log_level.warning')} </div> ) : null; return <div> diff --git a/server/sonar-web/src/main/js/apps/system/main.js b/server/sonar-web/src/main/js/apps/system/main.js index ef37a6600f0..17615da1265 100644 --- a/server/sonar-web/src/main/js/apps/system/main.js +++ b/server/sonar-web/src/main/js/apps/system/main.js @@ -21,6 +21,7 @@ import _ from 'underscore'; import React from 'react'; import { getSystemInfo } from '../../api/system'; import Section from './section'; +import { translate } from '../../helpers/l10n'; const SECTIONS_ORDER = ['SonarQube', 'Database', 'Plugins', 'System', 'ElasticSearch', 'JvmProperties', 'ComputeEngine']; @@ -62,7 +63,7 @@ export default React.createClass({ return <div className="page"> <header className="page-header"> - <h1 className="page-title">{window.t('system_info.page')}</h1> + <h1 className="page-title">{translate('system_info.page')}</h1> <div className="page-actions"> <a className="spacer-right" href={window.baseUrl + '/api/system/logs'} id="logs-link">Logs</a> <a href={window.baseUrl + '/api/system/info'} id="download-link">Download</a> diff --git a/server/sonar-web/src/main/js/components/charts/treemap.js b/server/sonar-web/src/main/js/components/charts/treemap.js index b1b316d86fa..09b95e1e151 100644 --- a/server/sonar-web/src/main/js/components/charts/treemap.js +++ b/server/sonar-web/src/main/js/components/charts/treemap.js @@ -24,6 +24,7 @@ import React from 'react'; import { TreemapBreadcrumbs } from './treemap-breadcrumbs'; import { ResizeMixin } from './../mixins/resize-mixin'; import { TooltipsMixin } from './../mixins/tooltips-mixin'; +import { translate } from '../../helpers/l10n'; const SIZE_SCALE = d3.scale.linear() @@ -121,7 +122,7 @@ export const Treemap = React.createClass({ renderWhenNoData () { return <div className="sonar-d3"> <div className="treemap-container" style={{ width: this.state.width, height: this.state.height }}> - {window.t('no_data')} + {translate('no_data')} </div> <TreemapBreadcrumbs {...this.props}/> </div>; diff --git a/server/sonar-web/src/main/js/components/common/select-list.js b/server/sonar-web/src/main/js/components/common/select-list.js index 39d3e68fac0..268910eb90e 100644 --- a/server/sonar-web/src/main/js/components/common/select-list.js +++ b/server/sonar-web/src/main/js/components/common/select-list.js @@ -20,6 +20,7 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; +import { translate } from '../../helpers/l10n'; var showError = null; @@ -251,7 +252,7 @@ var SelectListView = Backbone.View.extend({ this.listItemViews = []; showError = function (jqXHR) { - var message = window.t('default_error_message'); + var message = translate('default_error_message'); if (jqXHR != null && jqXHR.responseJSON != null && jqXHR.responseJSON.errors != null) { message = _.pluck(jqXHR.responseJSON.errors, 'msg').join('. '); } diff --git a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js index a326d93734b..841f1124812 100644 --- a/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/assign-form-view.js @@ -22,6 +22,7 @@ import _ from 'underscore'; import ActionOptionsView from '../../common/action-options-view'; import Template from '../templates/issue-assign-form.hbs'; import OptionTemplate from '../templates/issue-assign-form-option.hbs'; +import { translate } from '../../../helpers/l10n'; export default ActionOptionsView.extend({ template: Template, @@ -141,7 +142,7 @@ export default ActionOptionsView.extend({ if (this.assignees) { return this.assignees; } - var assignees = [{ id: '', text: window.t('unassigned') }], + var assignees = [{ id: '', text: translate('unassigned') }], currentUser = window.SS.user, currentUserName = window.SS.userName; assignees.push({ id: currentUser, text: currentUserName }); diff --git a/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js b/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js index d79be00fc0f..a2c46a9ab27 100644 --- a/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js +++ b/server/sonar-web/src/main/js/components/issue/views/plan-form-view.js @@ -21,6 +21,7 @@ import $ from 'jquery'; import _ from 'underscore'; import ActionOptionsView from '../../common/action-options-view'; import Template from '../templates/issue-plan-form.hbs'; +import { translate } from '../../../helpers/l10n'; export default ActionOptionsView.extend({ template: Template, @@ -45,7 +46,7 @@ export default ActionOptionsView.extend({ }, getActionPlans: function () { - return [{ key: '', name: window.t('issue.unplanned') }].concat(this.collection.toJSON()); + return [{ key: '', name: translate('issue.unplanned') }].concat(this.collection.toJSON()); }, serializeData: function () { diff --git a/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js b/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js index 57b6bed89f8..6dc53e04e51 100644 --- a/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js +++ b/server/sonar-web/src/main/js/components/navigator/filters/choice-filters.js @@ -23,6 +23,7 @@ import Backbone from 'backbone'; import BaseFilters from './base-filters'; import Template from '../templates/choice-filter.hbs'; import ItemTemplate from '../templates/choice-filter-item.hbs'; +import { translate } from '../../../helpers/l10n'; var DetailsChoiceFilterView = BaseFilters.DetailsFilterView.extend({ template: Template, @@ -269,7 +270,7 @@ var ChoiceFilterView = BaseFilters.BaseFilterView.extend({ }), defaultValue = this.model.has('defaultValue') ? this.model.get('defaultValue') : - this.model.get('multiple') ? window.t('all') : window.t('any'); + this.model.get('multiple') ? translate('all') : translate('any'); return this.isDefaultValue() ? defaultValue : value.join(', '); }, diff --git a/server/sonar-web/src/main/js/components/shared/assignee-helper.js b/server/sonar-web/src/main/js/components/shared/assignee-helper.js index f6600091b07..31e3e42f393 100644 --- a/server/sonar-web/src/main/js/components/shared/assignee-helper.js +++ b/server/sonar-web/src/main/js/components/shared/assignee-helper.js @@ -19,12 +19,13 @@ */ import React from 'react'; import Avatar from './avatar'; +import { translate } from '../../helpers/l10n'; export default class Assignee extends React.Component { render () { let avatar = this.props.user ? <span className="spacer-right"><Avatar email={this.props.user.email} size={16}/></span> : null; - let name = this.props.user ? this.props.user.name : window.t('unassigned'); + let name = this.props.user ? this.props.user.name : translate('unassigned'); return <span>{avatar}{name}</span>; } } diff --git a/server/sonar-web/src/main/js/components/shared/list-footer.js b/server/sonar-web/src/main/js/components/shared/list-footer.js index ad50cd8e80d..fc05b14c52b 100644 --- a/server/sonar-web/src/main/js/components/shared/list-footer.js +++ b/server/sonar-web/src/main/js/components/shared/list-footer.js @@ -19,6 +19,7 @@ */ import classNames from 'classnames'; import React from 'react'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ @@ -46,7 +47,7 @@ export default React.createClass({ renderLoading() { return <footer className="spacer-top note text-center"> - {window.t('loading')} + {translate('loading')} </footer>; }, diff --git a/server/sonar-web/src/main/js/components/shared/severity-helper.js b/server/sonar-web/src/main/js/components/shared/severity-helper.js index 5e5da357613..6e3ed4de918 100644 --- a/server/sonar-web/src/main/js/components/shared/severity-helper.js +++ b/server/sonar-web/src/main/js/components/shared/severity-helper.js @@ -19,6 +19,7 @@ */ import React from 'react'; import SeverityIcon from './severity-icon'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ render() { @@ -29,7 +30,7 @@ export default React.createClass({ <span className="spacer-right"> <SeverityIcon severity={this.props.severity}/> </span> - {window.t('severity', this.props.severity)} + {translate('severity', this.props.severity)} </span>; } }); diff --git a/server/sonar-web/src/main/js/components/shared/status-helper.js b/server/sonar-web/src/main/js/components/shared/status-helper.js index 17cf75ef4fa..42c2139238b 100644 --- a/server/sonar-web/src/main/js/components/shared/status-helper.js +++ b/server/sonar-web/src/main/js/components/shared/status-helper.js @@ -19,6 +19,7 @@ */ import React from 'react'; import StatusIcon from './status-icon'; +import { translate } from '../../helpers/l10n'; export default React.createClass({ render: function () { @@ -27,13 +28,13 @@ export default React.createClass({ } var resolution; if (this.props.resolution) { - resolution = 'Â (' + window.t('issue.resolution', this.props.resolution) + ')'; + resolution = 'Â (' + translate('issue.resolution', this.props.resolution) + ')'; } return ( <span> <StatusIcon status={this.props.status}/> - {window.t('issue.status', this.props.status)} + {translate('issue.status', this.props.status)} {resolution} </span> ); diff --git a/server/sonar-web/src/main/js/components/source-viewer/main.js b/server/sonar-web/src/main/js/components/source-viewer/main.js index a247f9a6715..738c3f4f58c 100644 --- a/server/sonar-web/src/main/js/components/source-viewer/main.js +++ b/server/sonar-web/src/main/js/components/source-viewer/main.js @@ -33,6 +33,7 @@ import LineActionsPopupView from './popups/line-actions-popup'; import highlightLocations from './helpers/code-with-issue-locations-helper'; import Template from './templates/source-viewer.hbs'; import IssueLocationTemplate from './templates/source-viewer-issue-location.hbs'; +import { translateWithParameters } from '../../helpers/l10n'; var HIGHLIGHTED_ROW_CLASS = 'source-line-highlighted'; @@ -730,7 +731,7 @@ export default Marionette.LayoutView.extend({ $(e.currentTarget).tooltip({ container: 'body', placement: 'right', - title: window.tp('source_viewer.tooltip.new_code', this.sinceLabel), + title: translateWithParameters('source_viewer.tooltip.new_code', this.sinceLabel), trigger: 'manual' }).tooltip('show'); }, diff --git a/server/sonar-web/src/main/js/helpers/handlebars/changelog.js b/server/sonar-web/src/main/js/helpers/handlebars/changelog.js index 35d7f34dcb2..8c01519e825 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/changelog.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/changelog.js @@ -17,16 +17,20 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { translate, translateWithParameters } from '../../helpers/l10n'; + module.exports = function (diff) { var message = ''; if (diff.newValue != null) { - message = window.tp('issue.changelog.changed_to', window.t('issue.changelog.field', diff.key), diff.newValue); + message = translateWithParameters('issue.changelog.changed_to', + translate('issue.changelog.field', diff.key), diff.newValue); } else { - message = window.tp('issue.changelog.removed', window.t('issue.changelog.field', diff.key)); + message = translateWithParameters('issue.changelog.removed', + translate('issue.changelog.field', diff.key)); } if (diff.oldValue != null) { message += ' ('; - message += window.tp('issue.changelog.was', diff.oldValue); + message += translateWithParameters('issue.changelog.was', diff.oldValue); message += ')'; } return message; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js b/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js index 9e4530dea1e..a49597edaf0 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/dashboardL10n.js @@ -17,9 +17,11 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { translate } from '../../helpers/l10n'; + module.exports = function (dashboardName) { var l10nKey = 'dashboard.' + dashboardName + '.name'; - var l10nLabel = window.t(l10nKey); + var l10nLabel = translate(l10nKey); if (l10nLabel !== l10nKey) { return l10nLabel; } else { diff --git a/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js b/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js index 6ede1867f74..9724fd19280 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/parameterChangelog.js @@ -18,15 +18,16 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import Handlebars from 'handlebars/runtime'; +import { translateWithParameters } from '../l10n'; module.exports = function (value, parameter) { if (parameter) { return new Handlebars.default.SafeString( - window.tp('quality_profiles.parameter_set_to_x', value, parameter) + translateWithParameters('quality_profiles.parameter_set_to_x', value, parameter) ); } else { return new Handlebars.default.SafeString( - window.tp('quality_profiles.changelog.parameter_reset_to_default_value_x', parameter) + translateWithParameters('quality_profiles.changelog.parameter_reset_to_default_value_x', parameter) ); } }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js b/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js index c8b444c0fe8..bb72085758f 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/severityChangelog.js @@ -18,9 +18,10 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import Handlebars from 'handlebars/runtime'; +import { translate, translateWithParameters } from '../../helpers/l10n'; module.exports = function (severity) { - var label = '<i class="icon-severity-' + severity.toLowerCase() + '"></i> ' + window.t('severity', severity), - message = window.tp('quality_profiles.severity_set_to_x', label); + var label = '<i class="icon-severity-' + severity.toLowerCase() + '"></i> ' + translate('severity', severity), + message = translateWithParameters('quality_profiles.severity_set_to_x', label); return new Handlebars.default.SafeString(message); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js b/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js index b9b3d2098b0..4a58f30a80e 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/severityHelper.js @@ -18,9 +18,10 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import Handlebars from 'handlebars/runtime'; +import { translate } from '../../helpers/l10n'; module.exports = function (severity) { return new Handlebars.default.SafeString( - '<i class="icon-severity-' + severity.toLowerCase() + '"></i> ' + window.t('severity', severity) + '<i class="icon-severity-' + severity.toLowerCase() + '"></i> ' + translate('severity', severity) ); }; diff --git a/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js b/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js index c339d73d288..aa0393ce376 100644 --- a/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js +++ b/server/sonar-web/src/main/js/helpers/handlebars/statusHelper.js @@ -18,11 +18,12 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import Handlebars from 'handlebars/runtime'; +import { translate } from '../../helpers/l10n'; module.exports = function (status, resolution) { - var s = '<i class="icon-status-' + status.toLowerCase() + '"></i> ' + window.t('issue.status', status); + var s = '<i class="icon-status-' + status.toLowerCase() + '"></i> ' + translate('issue.status', status); if (resolution != null) { - s = s + ' (' + window.t('issue.resolution', resolution) + ')'; + s = s + ' (' + translate('issue.resolution', resolution) + ')'; } return new Handlebars.default.SafeString(s); }; diff --git a/server/sonar-web/src/main/js/helpers/l10n.js b/server/sonar-web/src/main/js/helpers/l10n.js index 62ebe85e9c6..e3c2c2a9b91 100644 --- a/server/sonar-web/src/main/js/helpers/l10n.js +++ b/server/sonar-web/src/main/js/helpers/l10n.js @@ -17,8 +17,77 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { stringify } from 'querystring'; +import moment from 'moment'; + +let messages = {}; + +export function translate (...keys) { + const messageKey = keys.join('.'); + return messages[messageKey] || messageKey; +} + +export function translateWithParameters (messageKey, ...parameters) { + const message = messages[messageKey]; + if (message) { + return parameters.reduce((acc, parameter, index) => ( + acc.replace(`{${index}}`, parameter) + )); + } else { + return `${messageKey} ${parameters.join(' ')}`; + } +} + +function getCurrentLocale () { + const locale = window.navigator.languages ? window.navigator.languages[0] : window.navigator.language; + return locale.replace('-', '_'); +} + +function makeRequest (params) { + const url = `${window.baseUrl}/api/l10n/index?${stringify(params)}`; + + return fetch(url, { credentials: 'same-origin' }).then(response => { + if (response.status === 304) { + return JSON.parse(localStorage.getItem('l10n.bundle')); + } else if (response.status === 200) { + return response.json(); + } else { + throw new Error(response.status); + } + }); +} + +export function requestMessages () { + const currentLocale = getCurrentLocale(); + const cachedLocale = localStorage.getItem('l10n.locale'); + + if (cachedLocale !== currentLocale) { + localStorage.removeItem('l10n.timestamp'); + } + + const bundleTimestamp = localStorage.getItem('l10n.timestamp'); + const params = { locale: currentLocale }; + if (bundleTimestamp !== null) { + params.ts = bundleTimestamp; + } + + return makeRequest(params).then(bundle => { + const currentTimestamp = moment().format('YYYY-MM-DDTHH:mm:ssZZ'); + localStorage.setItem('l10n.timestamp', currentTimestamp); + localStorage.setItem('l10n.locale', currentLocale); + localStorage.setItem('l10n.bundle', JSON.stringify(bundle)); + messages = bundle; + }); +} + +export function installGlobal () { + window.t = translate; + window.tp = translateWithParameters; + window.requestMessages = requestMessages; +} + export function getLocalizedDashboardName (baseName) { var l10nKey = 'dashboard.' + baseName + '.name'; - var l10nLabel = window.t(l10nKey); + var l10nLabel = translate(l10nKey); return l10nLabel !== l10nKey ? l10nLabel : baseName; } diff --git a/server/sonar-web/src/main/js/helpers/measures.js b/server/sonar-web/src/main/js/helpers/measures.js index 12bf3980626..90f3045a171 100644 --- a/server/sonar-web/src/main/js/helpers/measures.js +++ b/server/sonar-web/src/main/js/helpers/measures.js @@ -19,6 +19,7 @@ */ import numeral from 'numeral'; import _ from 'underscore'; +import { translate, translateWithParameters } from './l10n'; /** @@ -49,7 +50,7 @@ export function formatMeasureVariation (value, type) { * @returns {string} */ export function localizeMetric (metricKey) { - return window.t('metric', metricKey, 'name'); + return translate('metric', metricKey, 'name'); } @@ -168,7 +169,7 @@ function ratingFormatter (value) { function levelFormatter (value) { var l10nKey = 'metric.level.' + value, - result = window.t(l10nKey); + result = translate(l10nKey); // if couldn't translate, return the initial value return l10nKey !== result ? result : value; } @@ -225,15 +226,17 @@ function addSpaceIfNeeded (value) { function formatDuration (isNegative, days, hours, minutes) { var formatted = ''; if (shouldDisplayDays(days)) { - formatted += window.tp('work_duration.x_days', isNegative ? -1 * days : days); + formatted += translateWithParameters('work_duration.x_days', isNegative ? -1 * days : days); } if (shouldDisplayHours(days, hours)) { formatted = addSpaceIfNeeded(formatted); - formatted += window.tp('work_duration.x_hours', isNegative && formatted.length === 0 ? -1 * hours : hours); + formatted += translateWithParameters('work_duration.x_hours', + isNegative && formatted.length === 0 ? -1 * hours : hours); } if (shouldDisplayMinutes(days, hours, minutes)) { formatted = addSpaceIfNeeded(formatted); - formatted += window.tp('work_duration.x_minutes', isNegative && formatted.length === 0 ? -1 * minutes : minutes); + formatted += translateWithParameters('work_duration.x_minutes', + isNegative && formatted.length === 0 ? -1 * minutes : minutes); } return formatted; } @@ -242,15 +245,17 @@ function formatDurationShort (isNegative, days, hours, minutes) { var formatted = ''; if (shouldDisplayDays(days)) { var formattedDays = formatMeasure(isNegative ? -1 * days : days, 'SHORT_INT'); - formatted += window.tp('work_duration.x_days', formattedDays); + formatted += translateWithParameters('work_duration.x_days', formattedDays); } if (shouldDisplayHoursInShortFormat(days, hours)) { formatted = addSpaceIfNeeded(formatted); - formatted += window.tp('work_duration.x_hours', isNegative && formatted.length === 0 ? -1 * hours : hours); + formatted += translateWithParameters('work_duration.x_hours', + isNegative && formatted.length === 0 ? -1 * hours : hours); } if (shouldDisplayMinutesInShortFormat(days, hours, minutes)) { formatted = addSpaceIfNeeded(formatted); - formatted += window.tp('work_duration.x_minutes', isNegative && formatted.length === 0 ? -1 * minutes : minutes); + formatted += translateWithParameters('work_duration.x_minutes', + isNegative && formatted.length === 0 ? -1 * minutes : minutes); } return formatted; } diff --git a/server/sonar-web/src/main/js/libs/sonar.js b/server/sonar-web/src/main/js/libs/sonar.js index 670e8940290..a245d4142d4 100644 --- a/server/sonar-web/src/main/js/libs/sonar.js +++ b/server/sonar-web/src/main/js/libs/sonar.js @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -require('script!./translate.js'); require('script!./third-party/jquery-ui.js'); require('script!./third-party/select2.js'); require('script!./third-party/keymaster.js'); diff --git a/server/sonar-web/src/main/js/libs/translate.js b/server/sonar-web/src/main/js/libs/translate.js deleted file mode 100644 index ddd4bc6b38f..00000000000 --- a/server/sonar-web/src/main/js/libs/translate.js +++ /dev/null @@ -1,106 +0,0 @@ -/* - * SonarQube :: Web - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -(function() { - window.suppressTranslationWarnings = false; - - window.t = function() { - if (!window.messages) { - return window.translate.apply(this, arguments); - } - - var args = Array.prototype.slice.call(arguments, 0), - key = args.join('.'); - return window.messages[key] != null ? window.messages[key] : key; - }; - - window.tp = function() { - var args = Array.prototype.slice.call(arguments, 0), - key = args.shift(), - message = window.messages[key]; - if (message) { - args.forEach(function(p, i) { - message = message.replace('{' + i + '}', p); - }); - } - return message || (key + ' ' + args.join(' ')); - }; - - - 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 && window.SS.phrases, - found = !!start, - result = ''; - - if (found) { - result = tokens.reduce(function(prev, current) { - if (!current || !prev[current]) { - found = false; - } - return current ? prev[current] : prev; - }, start); - } - - return found ? result : key; - }; - - - window.requestMessages = function() { - var currentLocale = window.pageLang, - cachedLocale = localStorage.getItem('l10n.locale'); - if (cachedLocale !== currentLocale) { - localStorage.removeItem('l10n.timestamp'); - } - - var bundleTimestamp = localStorage.getItem('l10n.timestamp'), - params = { locale: currentLocale }; - if (bundleTimestamp !== null) { - params.ts = bundleTimestamp; - } - - var apiUrl = baseUrl + '/api/l10n/index'; - return jQuery.ajax({ - url: apiUrl, - data: params, - dataType: 'json', - statusCode: { - 304: function() { - window.messages = JSON.parse(localStorage.getItem('l10n.bundle')); - } - } - }).done(function(bundle, textStatus, jqXHR) { - if(bundle !== undefined) { - bundleTimestamp = new Date().toISOString(); - bundleTimestamp = bundleTimestamp.substr(0, bundleTimestamp.indexOf('.')) + '+0000'; - localStorage.setItem('l10n.timestamp', bundleTimestamp); - localStorage.setItem('l10n.locale', currentLocale); - - window.messages = bundle; - localStorage.setItem('l10n.bundle', JSON.stringify(bundle)); - } else if (jqXHR.status === 304) { - window.messages = JSON.parse(localStorage.getItem('l10n.bundle')); - } - }); - }; -})(); diff --git a/server/sonar-web/src/main/js/main/app.js b/server/sonar-web/src/main/js/main/app.js index f4242a6d1f4..b4b73492323 100644 --- a/server/sonar-web/src/main/js/main/app.js +++ b/server/sonar-web/src/main/js/main/app.js @@ -27,6 +27,7 @@ import moment from 'moment'; import numeral from 'numeral'; import './processes'; import Navigation from './nav/app'; +import { installGlobal, requestMessages } from '../helpers/l10n'; // set the Backbone's $ Backbone.$ = $; @@ -34,7 +35,8 @@ Backbone.$ = $; function requestLocalizationBundle () { if (!window.sonarqube.bannedNavigation) { - return new Promise(resolve => window.requestMessages().done(resolve)); + installGlobal(); + return requestMessages(); } else { return Promise.resolve(); } diff --git a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js index d0f94010206..9647ee60cda 100644 --- a/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-menu.js @@ -23,7 +23,7 @@ import classNames from 'classnames'; import React from 'react'; import LinksMixin from '../links-mixin'; -import { getLocalizedDashboardName } from '../../../helpers/l10n'; +import { translate, getLocalizedDashboardName } from '../../../helpers/l10n'; import { getComponentDashboardUrl, getComponentFixedDashboardUrl, @@ -110,7 +110,7 @@ export default React.createClass({ let key = 'fixed-dashboard-' + fixedDashboard.link.substr(1); let url = getComponentFixedDashboardUrl(this.props.component.key, fixedDashboard.link); let name = fixedDashboard.link !== '' ? - window.t(fixedDashboard.name) : <i className="icon-home"/>; + translate(fixedDashboard.name) : <i className="icon-home"/>; let className = classNames({ active: this.isFixedDashboardActive(fixedDashboard) }); return <li key={key} className={className}> <a href={url}>{name}</a> @@ -134,7 +134,7 @@ export default React.createClass({ const managementLink = this.renderDashboardsManagementLink(); return <li className={className}> <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {window.t('layout.dashboards')} + {translate('layout.dashboards')} <i className="icon-dropdown"/> </a> <ul className="dropdown-menu"> @@ -151,7 +151,7 @@ export default React.createClass({ } let key = 'dashboard-management'; let url = getComponentDashboardManagementUrl(this.props.component.key); - let name = window.t('dashboard.manage_dashboards'); + let name = translate('dashboard.manage_dashboards'); let className = classNames('pill-right', { active: this.isDashboardManagementActive() }); return <li key={key} className={className}> <a className="note" href={url}>{name}</a> @@ -164,17 +164,17 @@ export default React.createClass({ } const url = `/code/index?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('code.page'), '/code'); + return this.renderLink(url, translate('code.page'), '/code'); }, renderComponentsLink() { const url = `/components/index?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('components.page'), '/components'); + return this.renderLink(url, translate('components.page'), '/components'); }, renderComponentIssuesLink() { const url = `/component_issues/index?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('issues.page'), '/component_issues'); + return this.renderLink(url, translate('issues.page'), '/component_issues'); }, renderAdministration() { @@ -200,7 +200,7 @@ export default React.createClass({ return ( <li className={className}> <a className="dropdown-toggle navbar-admin-link" data-toggle="dropdown" href="#"> - {window.t('layout.settings')} + {translate('layout.settings')} <i className="icon-dropdown"/> </a> <ul className="dropdown-menu"> @@ -226,7 +226,7 @@ export default React.createClass({ return null; } const url = `/project/settings?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('project_settings.page'), '/project/settings'); + return this.renderLink(url, translate('project_settings.page'), '/project/settings'); }, renderProfilesLink() { @@ -234,7 +234,7 @@ export default React.createClass({ return null; } const url = `/project/profile?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('project_quality_profiles.page'), '/project/profile'); + return this.renderLink(url, translate('project_quality_profiles.page'), '/project/profile'); }, renderQualityGatesLink() { @@ -242,7 +242,7 @@ export default React.createClass({ return null; } const url = `/project/qualitygate?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('project_quality_gate.page'), '/project/qualitygate'); + return this.renderLink(url, translate('project_quality_gate.page'), '/project/qualitygate'); }, renderCustomMeasuresLink() { @@ -250,7 +250,7 @@ export default React.createClass({ return null; } const url = `/custom_measures?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('custom_measures.page'), '/custom_measures'); + return this.renderLink(url, translate('custom_measures.page'), '/custom_measures'); }, renderActionPlansLink() { @@ -258,7 +258,7 @@ export default React.createClass({ return null; } const url = `/action_plans?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('action_plans.page'), '/action_plans'); + return this.renderLink(url, translate('action_plans.page'), '/action_plans'); }, renderLinksLink() { @@ -266,7 +266,7 @@ export default React.createClass({ return null; } const url = `/project/links?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('project_links.page'), '/project/links'); + return this.renderLink(url, translate('project_links.page'), '/project/links'); }, renderPermissionsLink() { @@ -274,7 +274,7 @@ export default React.createClass({ return null; } const url = `/project_roles?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('permissions.page'), '/project_roles'); + return this.renderLink(url, translate('permissions.page'), '/project_roles'); }, renderHistoryLink() { @@ -282,7 +282,7 @@ export default React.createClass({ return null; } const url = `/project/history?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('project_history.page'), '/project/history'); + return this.renderLink(url, translate('project_history.page'), '/project/history'); }, renderBackgroundTasksLink() { @@ -290,7 +290,7 @@ export default React.createClass({ return null; } const url = `/project/background_tasks?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('background_tasks.page'), '/project/background_tasks'); + return this.renderLink(url, translate('background_tasks.page'), '/project/background_tasks'); }, renderUpdateKeyLink() { @@ -298,7 +298,7 @@ export default React.createClass({ return null; } const url = `/project/key?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('update_key.page'), '/project/key'); + return this.renderLink(url, translate('update_key.page'), '/project/key'); }, renderDeletionLink() { @@ -306,7 +306,7 @@ export default React.createClass({ return null; } const url = `/project/deletion?id=${encodeURIComponent(this.props.component.key)}`; - return this.renderLink(url, window.t('deletion.page'), '/project/deletion'); + return this.renderLink(url, translate('deletion.page'), '/project/deletion'); }, renderExtensions() { diff --git a/server/sonar-web/src/main/js/main/nav/component/component-nav-meta.js b/server/sonar-web/src/main/js/main/nav/component/component-nav-meta.js index 93ff6b4d9a7..1fda8054c70 100644 --- a/server/sonar-web/src/main/js/main/nav/component/component-nav-meta.js +++ b/server/sonar-web/src/main/js/main/nav/component/component-nav-meta.js @@ -20,6 +20,7 @@ import moment from 'moment'; import React from 'react'; import PendingIcon from '../../../components/shared/pending-icon'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; export default React.createClass({ render() { @@ -29,31 +30,31 @@ export default React.createClass({ if (this.props.isInProgress) { let tooltip = canSeeBackgroundTasks ? - window.tp('component_navigation.status.in_progress.admin', backgroundTasksUrl) : - window.t('component_navigation.status.in_progress'); + translateWithParameters('component_navigation.status.in_progress.admin', backgroundTasksUrl) : + translate('component_navigation.status.in_progress'); metaList.push( <li key="isInProgress" data-toggle="tooltip" title={tooltip}> <i className="spinner" style={{ marginTop: '-1px' }}/> {' '} - <span className="text-info">{window.t('background_task.status.IN_PROGRESS')}</span> + <span className="text-info">{translate('background_task.status.IN_PROGRESS')}</span> </li> ); } else if (this.props.isPending) { let tooltip = canSeeBackgroundTasks ? - window.tp('component_navigation.status.pending.admin', backgroundTasksUrl) : - window.t('component_navigation.status.pending'); + translateWithParameters('component_navigation.status.pending.admin', backgroundTasksUrl) : + translate('component_navigation.status.pending'); metaList.push( <li key="isPending" data-toggle="tooltip" title={tooltip}> - <PendingIcon/> <span>{window.t('background_task.status.PENDING')}</span> + <PendingIcon/> <span>{translate('background_task.status.PENDING')}</span> </li> ); } else if (this.props.isFailed) { let tooltip = canSeeBackgroundTasks ? - window.tp('component_navigation.status.failed.admin', backgroundTasksUrl) : - window.t('component_navigation.status.failed'); + translateWithParameters('component_navigation.status.failed.admin', backgroundTasksUrl) : + translate('component_navigation.status.failed'); metaList.push( <li key="isFailed" data-toggle="tooltip" title={tooltip}> - <span className="badge badge-danger">{window.t('background_task.status.FAILED')}</span> + <span className="badge badge-danger">{translate('background_task.status.FAILED')}</span> </li> ); } diff --git a/server/sonar-web/src/main/js/main/nav/dashboard-name-mixin.js b/server/sonar-web/src/main/js/main/nav/dashboard-name-mixin.js index 22635fb1a63..c32863fc706 100644 --- a/server/sonar-web/src/main/js/main/nav/dashboard-name-mixin.js +++ b/server/sonar-web/src/main/js/main/nav/dashboard-name-mixin.js @@ -17,10 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { translate } from '../../helpers/l10n'; + export default { getLocalizedDashboardName(baseName) { var l10nKey = 'dashboard.' + baseName + '.name'; - var l10nLabel = window.t(l10nKey); + var l10nLabel = translate(l10nKey); if (l10nLabel !== l10nKey) { return l10nLabel; } else { diff --git a/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js b/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js index 5f0ca474b94..419fa8f09ea 100644 --- a/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-branding.js @@ -18,13 +18,14 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React from 'react'; +import { translate } from '../../../helpers/l10n'; export default React.createClass({ renderLogo() { let url = this.props.logoUrl || `${window.baseUrl}/images/logo.svg`; let width = this.props.logoWidth || 100; let height = 30; - let title = window.t('layout.sonar.slogan'); + let title = translate('layout.sonar.slogan'); return <img src={url} width={width} height={height} diff --git a/server/sonar-web/src/main/js/main/nav/global/global-nav-menu.js b/server/sonar-web/src/main/js/main/nav/global/global-nav-menu.js index ce94d0ff2a5..4362887193d 100644 --- a/server/sonar-web/src/main/js/main/nav/global/global-nav-menu.js +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-menu.js @@ -20,6 +20,7 @@ import React from 'react'; import DashboardNameMixin from '../dashboard-name-mixin'; import LinksMixin from '../links-mixin'; +import { translate } from '../../../helpers/l10n'; export default React.createClass({ mixins: [DashboardNameMixin, LinksMixin], @@ -42,7 +43,7 @@ export default React.createClass({ const url = `${window.baseUrl}/dashboards`; return ( <li> - <a href={url}>{window.t('dashboard.manage_dashboards')}</a> + <a href={url}>{translate('dashboard.manage_dashboards')}</a> </li> ); }, @@ -53,7 +54,7 @@ export default React.createClass({ return ( <li className="dropdown"> <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {window.t('layout.dashboards')} <span className="icon-dropdown"/> + {translate('layout.dashboards')} <span className="icon-dropdown"/> </a> <ul className="dropdown-menu"> {dashboards} @@ -68,7 +69,7 @@ export default React.createClass({ const url = `${window.baseUrl}/issues/search`; return ( <li className={this.activeLink('/issues')}> - <a href={url}>{window.t('issues.page')}</a> + <a href={url}>{translate('issues.page')}</a> </li> ); }, @@ -77,7 +78,7 @@ export default React.createClass({ const url = `${window.baseUrl}/measures/search?qualifiers[]=TRK`; return ( <li className={this.activeLink('/measures')}> - <a href={url}>{window.t('layout.measures')}</a> + <a href={url}>{translate('layout.measures')}</a> </li> ); }, @@ -86,7 +87,7 @@ export default React.createClass({ const url = `${window.baseUrl}/coding_rules`; return ( <li className={this.activeLink('/coding_rules')}> - <a href={url}>{window.t('coding_rules.page')}</a> + <a href={url}>{translate('coding_rules.page')}</a> </li> ); }, @@ -95,7 +96,7 @@ export default React.createClass({ const url = `${window.baseUrl}/profiles`; return ( <li className={this.activeLink('/profiles')}> - <a href={url}>{window.t('quality_profiles.page')}</a> + <a href={url}>{translate('quality_profiles.page')}</a> </li> ); }, @@ -104,7 +105,7 @@ export default React.createClass({ const url = `${window.baseUrl}/quality_gates`; return ( <li className={this.activeLink('/quality_gates')}> - <a href={url}>{window.t('quality_gates.page')}</a> + <a href={url}>{translate('quality_gates.page')}</a> </li> ); }, @@ -116,7 +117,7 @@ export default React.createClass({ const url = `${window.baseUrl}/settings`; return ( <li className={this.activeLink('/settings')}> - <a className="navbar-admin-link" href={url}>{window.t('layout.settings')}</a> + <a className="navbar-admin-link" href={url}>{translate('layout.settings')}</a> </li> ); }, @@ -125,7 +126,7 @@ export default React.createClass({ const url = `${window.baseUrl}/comparison`; return ( <li className={this.activeLink('/comparison')}> - <a href={url}>{window.t('comparison_global.page')}</a> + <a href={url}>{translate('comparison_global.page')}</a> </li> ); }, @@ -144,7 +145,7 @@ export default React.createClass({ return ( <li className="dropdown"> <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {window.t('more')} <span className="icon-dropdown"/> + {translate('more')} <span className="icon-dropdown"/> </a> <ul className="dropdown-menu"> {this.renderComparisonLink()} diff --git a/server/sonar-web/src/main/js/main/nav/global/global-nav-user.js b/server/sonar-web/src/main/js/main/nav/global/global-nav-user.js index 18022141a2e..3d29e810986 100644 --- a/server/sonar-web/src/main/js/main/nav/global/global-nav-user.js +++ b/server/sonar-web/src/main/js/main/nav/global/global-nav-user.js @@ -20,6 +20,7 @@ import React from 'react'; import Avatar from '../../../components/shared/avatar'; import RecentHistory from '../component/recent-history'; +import { translate } from '../../../helpers/l10n'; export default React.createClass({ renderAuthenticated() { @@ -31,10 +32,10 @@ export default React.createClass({ </a> <ul className="dropdown-menu dropdown-menu-right"> <li> - <a href={`${window.baseUrl}/account/index`}>{window.t('layout.user_panel.my_profile')}</a> + <a href={`${window.baseUrl}/account/index`}>{translate('layout.user_panel.my_profile')}</a> </li> <li> - <a onClick={this.handleLogout} href="#">{window.t('layout.logout')}</a> + <a onClick={this.handleLogout} href="#">{translate('layout.logout')}</a> </li> </ul> </li> @@ -44,7 +45,7 @@ export default React.createClass({ renderAnonymous() { return ( <li> - <a onClick={this.handleLogin} href="#">{window.t('layout.login')}</a> + <a onClick={this.handleLogin} href="#">{translate('layout.login')}</a> </li> ); }, diff --git a/server/sonar-web/src/main/js/main/nav/global/search-view.js b/server/sonar-web/src/main/js/main/nav/global/search-view.js index 6a37a7c88f7..b70700527cc 100644 --- a/server/sonar-web/src/main/js/main/nav/global/search-view.js +++ b/server/sonar-web/src/main/js/main/nav/global/search-view.js @@ -26,6 +26,7 @@ import SearchItemTemplate from '../templates/nav-search-item.hbs'; import EmptySearchTemplate from '../templates/nav-search-empty.hbs'; import SearchTemplate from '../templates/nav-search.hbs'; import RecentHistory from '../component/recent-history'; +import { translate } from '../../../helpers/l10n'; var SearchItemView = Marionette.ItemView.extend({ tagName: 'li', @@ -174,16 +175,16 @@ export default Marionette.LayoutView.extend({ url: url, name: historyItem.name, q: historyItem.icon, - extra: index === 0 ? window.t('browsed_recently') : null + extra: index === 0 ? translate('browsed_recently') : null }; }), favorite = _.first(this.favorite, 6).map(function (f, index) { - return _.extend(f, { extra: index === 0 ? window.t('favorite') : null }); + return _.extend(f, { extra: index === 0 ? translate('favorite') : null }); }), qualifiers = this.model.get('qualifiers').map(function (q, index) { return { url: baseUrl + '/all_projects?qualifier=' + encodeURIComponent(q), - name: window.t('qualifiers.all', q), + name: translate('qualifiers.all', q), extra: index === 0 ? '' : null }; }); @@ -220,22 +221,22 @@ export default Marionette.LayoutView.extend({ getNavigationFindings: function (q) { var DEFAULT_ITEMS = [ - { name: window.t('issues.page'), url: baseUrl + '/issues/search' }, - { name: window.t('layout.measures'), url: baseUrl + '/measures/search?qualifiers[]=TRK' }, - { name: window.t('coding_rules.page'), url: baseUrl + '/coding_rules' }, - { name: window.t('quality_profiles.page'), url: baseUrl + '/profiles' }, - { name: window.t('quality_gates.page'), url: baseUrl + '/quality_gates' }, - { name: window.t('comparison_global.page'), url: baseUrl + '/comparison' } + { name: translate('issues.page'), url: baseUrl + '/issues/search' }, + { name: translate('layout.measures'), url: baseUrl + '/measures/search?qualifiers[]=TRK' }, + { name: translate('coding_rules.page'), url: baseUrl + '/coding_rules' }, + { name: translate('quality_profiles.page'), url: baseUrl + '/profiles' }, + { name: translate('quality_gates.page'), url: baseUrl + '/quality_gates' }, + { name: translate('comparison_global.page'), url: baseUrl + '/comparison' } ], customItems = []; if (window.SS.isUserAdmin) { - customItems.push({ name: window.t('layout.settings'), url: baseUrl + '/settings' }); + customItems.push({ name: translate('layout.settings'), url: baseUrl + '/settings' }); } var findings = [].concat(DEFAULT_ITEMS, customItems).filter(function (f) { return f.name.match(new RegExp(q, 'i')); }); if (findings.length > 0) { - findings[0].extra = window.t('navigation'); + findings[0].extra = translate('navigation'); } return _.first(findings, 6); }, @@ -249,7 +250,7 @@ export default Marionette.LayoutView.extend({ return f.name.match(new RegExp(q, 'i')); }); if (findings.length > 0) { - findings[0].extra = window.t('dashboard.global_dashboards'); + findings[0].extra = translate('dashboard.global_dashboards'); } return _.first(findings, 6); }, @@ -259,7 +260,7 @@ export default Marionette.LayoutView.extend({ return f.name.match(new RegExp(q, 'i')); }); if (findings.length > 0) { - findings[0].extra = window.t('favorite'); + findings[0].extra = translate('favorite'); } return _.first(findings, 6); } diff --git a/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js b/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js index cca1222c8be..be442865445 100644 --- a/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js +++ b/server/sonar-web/src/main/js/main/nav/settings/settings-nav.js @@ -19,6 +19,7 @@ */ import React from 'react'; import LinksMixin from '../links-mixin'; +import { translate } from '../../../helpers/l10n'; export default React.createClass({ mixins: [LinksMixin], @@ -31,52 +32,52 @@ export default React.createClass({ return ( <div className="container"> <ul className="nav navbar-nav nav-crumbs"> - {this.renderLink('/settings', window.t('layout.settings'))} + {this.renderLink('/settings', translate('layout.settings'))} </ul> <ul className="nav navbar-nav nav-tabs"> <li className="dropdown"> <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {window.t('sidebar.project_settings')} <i className="icon-dropdown"></i> + {translate('sidebar.project_settings')} <i className="icon-dropdown"></i> </a> <ul className="dropdown-menu"> - {this.renderLink('/settings', window.t('settings.page'))} + {this.renderLink('/settings', translate('settings.page'))} {this.renderLink('/metrics', 'Custom Metrics')} - {this.renderLink('/admin_dashboards', window.t('default_dashboards.page'))} + {this.renderLink('/admin_dashboards', translate('default_dashboards.page'))} {this.props.extensions.map(e => this.renderLink(e.url, e.name))} </ul> </li> <li className="dropdown"> <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {window.t('sidebar.security')} <i className="icon-dropdown"></i> + {translate('sidebar.security')} <i className="icon-dropdown"></i> </a> <ul className="dropdown-menu"> - {this.renderLink('/users', window.t('users.page'))} - {this.renderLink('/groups', window.t('user_groups.page'))} - {this.renderLink('/roles/global', window.t('global_permissions.page'))} - {this.renderLink('/roles/projects', window.t('roles.page'))} - {this.renderLink('/permission_templates', window.t('permission_templates'))} + {this.renderLink('/users', translate('users.page'))} + {this.renderLink('/groups', translate('user_groups.page'))} + {this.renderLink('/roles/global', translate('global_permissions.page'))} + {this.renderLink('/roles/projects', translate('roles.page'))} + {this.renderLink('/permission_templates', translate('permission_templates'))} </ul> </li> <li className="dropdown"> <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {window.t('sidebar.projects')} <i className="icon-dropdown"></i> + {translate('sidebar.projects')} <i className="icon-dropdown"></i> </a> <ul className="dropdown-menu"> {this.renderLink('/projects', 'Management')} - {this.renderLink('/background_tasks', window.t('background_tasks.page'))} + {this.renderLink('/background_tasks', translate('background_tasks.page'))} </ul> </li> <li className="dropdown"> <a className="dropdown-toggle" data-toggle="dropdown" href="#"> - {window.t('sidebar.system')} <i className="icon-dropdown"></i> + {translate('sidebar.system')} <i className="icon-dropdown"></i> </a> <ul className="dropdown-menu"> - {this.renderLink('/updatecenter', window.t('update_center.page'))} - {this.renderLink('/system', window.t('system_info.page'))} + {this.renderLink('/updatecenter', translate('update_center.page'))} + {this.renderLink('/system', translate('system_info.page'))} </ul> </li> </ul> diff --git a/server/sonar-web/src/main/js/main/processes.js b/server/sonar-web/src/main/js/main/processes.js index 0d95d84dd30..81f7c2f9354 100644 --- a/server/sonar-web/src/main/js/main/processes.js +++ b/server/sonar-web/src/main/js/main/processes.js @@ -21,6 +21,7 @@ import $ from 'jquery'; import _ from 'underscore'; import Backbone from 'backbone'; import Marionette from 'backbone.marionette'; +import { translate } from '../helpers/l10n'; var defaults = { queue: {}, @@ -49,7 +50,7 @@ var Process = Backbone.Model.extend({ fail: function (message) { var that = this, - msg = message || window.t('process.fail'); + msg = message || translate('process.fail'); if (msg === 'process.fail') { // no translation msg = 'An error happened, some parts of the page might not render correctly. ' + diff --git a/server/sonar-web/src/main/js/widgets/old/tag-cloud.js b/server/sonar-web/src/main/js/widgets/old/tag-cloud.js index 46d806da52e..bc7da015595 100644 --- a/server/sonar-web/src/main/js/widgets/old/tag-cloud.js +++ b/server/sonar-web/src/main/js/widgets/old/tag-cloud.js @@ -17,6 +17,8 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { translate } from '../../helpers/l10n'; + (function () { function TagCloud () { @@ -83,7 +85,7 @@ TagCloud.prototype.tooltip = function (d) { var suffixKey = d.value === 1 ? 'issue' : 'issues', - suffix = window.t(suffixKey); + suffix = translate(suffixKey); return (d.value + '\u00a0') + suffix; }; diff --git a/server/sonar-web/src/main/js/widgets/old/treemap.js b/server/sonar-web/src/main/js/widgets/old/treemap.js index ffc4faf67b5..4d8801d804b 100644 --- a/server/sonar-web/src/main/js/widgets/old/treemap.js +++ b/server/sonar-web/src/main/js/widgets/old/treemap.js @@ -19,6 +19,7 @@ */ import $ from 'jquery'; import _ from 'underscore'; +import { translate } from '../../helpers/l10n'; (function () { @@ -56,7 +57,7 @@ import _ from 'underscore'; this.filterComponents(); if (!this.components().length) { this.maxResultsReachedLabel - .text(window.t('treemap.all_measures_undefined')) + .text(translate('treemap.all_measures_undefined')) .style('display', 'block'); return; } |