Browse Source

SONAR-8828 Make sure all messages can be localized (#2600)

tags/6.6-RC1
Stas Vilchik 6 years ago
parent
commit
b66f125104
81 changed files with 479 additions and 1047 deletions
  1. 2
    2
      server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js
  2. 2
    2
      server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.js.snap
  3. 4
    2
      server/sonar-web/src/main/js/apps/account/notifications/Projects.js
  4. 9
    6
      server/sonar-web/src/main/js/apps/account/notifications/__tests__/__snapshots__/Projects-test.js.snap
  5. 3
    2
      server/sonar-web/src/main/js/apps/account/profile/Profile.js
  6. 11
    13
      server/sonar-web/src/main/js/apps/account/templates/account-tokens.hbs
  7. 6
    1
      server/sonar-web/src/main/js/apps/account/tokens-view.js
  8. 3
    2
      server/sonar-web/src/main/js/apps/background-tasks/components/DateFilter.js
  9. 10
    6
      server/sonar-web/src/main/js/apps/background-tasks/components/Search.js
  10. 4
    0
      server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js
  11. 4
    5
      server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-meta.hbs
  12. 4
    4
      server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-delete.hbs
  13. 6
    6
      server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-form.hbs
  14. 2
    2
      server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-list-footer.hbs
  15. 4
    4
      server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-list-item.hbs
  16. 4
    4
      server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-list.hbs
  17. 4
    4
      server/sonar-web/src/main/js/apps/groups/templates/groups-delete.hbs
  18. 5
    5
      server/sonar-web/src/main/js/apps/groups/templates/groups-form.hbs
  19. 1
    1
      server/sonar-web/src/main/js/apps/groups/templates/groups-header.hbs
  20. 2
    2
      server/sonar-web/src/main/js/apps/groups/templates/groups-list-footer.hbs
  21. 3
    3
      server/sonar-web/src/main/js/apps/groups/templates/groups-list-item.hbs
  22. 1
    1
      server/sonar-web/src/main/js/apps/groups/templates/groups-list.hbs
  23. 1
    1
      server/sonar-web/src/main/js/apps/groups/templates/groups-search.hbs
  24. 2
    2
      server/sonar-web/src/main/js/apps/groups/templates/groups-users.hbs
  25. 2
    2
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-failed.hbs
  26. 2
    2
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-not-supported.hbs
  27. 5
    5
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-required.hbs
  28. 2
    2
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-running.hbs
  29. 2
    2
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-succeeded.hbs
  30. 2
    2
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-no-migration.hbs
  31. 3
    3
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-down.hbs
  32. 3
    7
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-migration.hbs
  33. 1
    1
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-starting.hbs
  34. 3
    3
      server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-up.hbs
  35. 4
    4
      server/sonar-web/src/main/js/apps/metrics/templates/metrics-delete.hbs
  36. 8
    8
      server/sonar-web/src/main/js/apps/metrics/templates/metrics-form.hbs
  37. 3
    4
      server/sonar-web/src/main/js/apps/metrics/templates/metrics-header.hbs
  38. 2
    2
      server/sonar-web/src/main/js/apps/metrics/templates/metrics-list-footer.hbs
  39. 2
    2
      server/sonar-web/src/main/js/apps/metrics/templates/metrics-list-item.hbs
  40. 2
    2
      server/sonar-web/src/main/js/apps/overview/main/enhance.js
  41. 2
    2
      server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js
  42. 2
    2
      server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js
  43. 3
    3
      server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js
  44. 4
    12
      server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/__snapshots__/Defaults-test.js.snap
  45. 4
    4
      server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-delete.hbs
  46. 8
    8
      server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-form.hbs
  47. 1
    1
      server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js
  48. 4
    4
      server/sonar-web/src/main/js/apps/permissions/project/templates/ApplyTemplateTemplate.hbs
  49. 3
    2
      server/sonar-web/src/main/js/apps/permissions/shared/components/HoldersList.js
  50. 3
    3
      server/sonar-web/src/main/js/apps/permissions/shared/components/SearchForm.js
  51. 1
    1
      server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx
  52. 2
    2
      server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/Search-test.tsx.snap
  53. 2
    2
      server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx
  54. 1
    0
      server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx
  55. 10
    14
      server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.js
  56. 12
    32
      server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.js
  57. 1
    1
      server/sonar-web/src/main/js/apps/settings/serverId/ServerIdApp.js
  58. 6
    6
      server/sonar-web/src/main/js/apps/update-center/templates/_update-center-plugin-actions.hbs
  59. 1
    1
      server/sonar-web/src/main/js/apps/update-center/templates/_update-center-plugin-changelog-entry.hbs
  60. 1
    1
      server/sonar-web/src/main/js/apps/update-center/templates/update-center-footer.hbs
  61. 6
    6
      server/sonar-web/src/main/js/apps/update-center/templates/update-center-header.hbs
  62. 1
    1
      server/sonar-web/src/main/js/apps/update-center/templates/update-center-plugin-changelog.hbs
  63. 10
    10
      server/sonar-web/src/main/js/apps/update-center/templates/update-center-plugin.hbs
  64. 8
    8
      server/sonar-web/src/main/js/apps/update-center/templates/update-center-search.hbs
  65. 10
    11
      server/sonar-web/src/main/js/apps/update-center/templates/update-center-system-update.hbs
  66. 6
    6
      server/sonar-web/src/main/js/apps/users/templates/users-change-password.hbs
  67. 4
    4
      server/sonar-web/src/main/js/apps/users/templates/users-deactivate.hbs
  68. 10
    10
      server/sonar-web/src/main/js/apps/users/templates/users-form.hbs
  69. 2
    2
      server/sonar-web/src/main/js/apps/users/templates/users-groups.hbs
  70. 1
    1
      server/sonar-web/src/main/js/apps/users/templates/users-header.hbs
  71. 2
    2
      server/sonar-web/src/main/js/apps/users/templates/users-list-footer.hbs
  72. 7
    7
      server/sonar-web/src/main/js/apps/users/templates/users-list-item.hbs
  73. 3
    3
      server/sonar-web/src/main/js/apps/users/templates/users-list.hbs
  74. 1
    1
      server/sonar-web/src/main/js/apps/users/templates/users-search.hbs
  75. 12
    12
      server/sonar-web/src/main/js/apps/users/templates/users-tokens.hbs
  76. 6
    1
      server/sonar-web/src/main/js/apps/users/tokens-view.js
  77. 5
    2
      server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js
  78. 1
    1
      server/sonar-web/src/main/js/components/SourceViewer/views/templates/_source-viewer-measures-duplications.hbs
  79. 1
    1
      server/sonar-web/src/main/js/components/SourceViewer/views/templates/_source-viewer-measures-lines.hbs
  80. 168
    725
      sonar-core/src/main/resources/org/sonar/l10n/core.properties
  81. 1
    1
      sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java

+ 2
- 2
server/sonar-web/src/main/js/app/components/nav/settings/SettingsNav.js View File

@@ -116,7 +116,7 @@ class SettingsNav extends React.PureComponent {
</li>
<li>
<IndexLink to="/admin/custom_metrics" activeClassName="active">
Custom Metrics
{translate('custom_metrics.page')}
</IndexLink>
</li>
{this.props.extensions.map(this.renderExtension)}
@@ -165,7 +165,7 @@ class SettingsNav extends React.PureComponent {
{!this.props.customOrganizations && (
<li>
<IndexLink to="/admin/projects_management" activeClassName="active">
Management
{translate('management')}
</IndexLink>
</li>
)}

+ 2
- 2
server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/SettingsNav-test.js.snap View File

@@ -68,7 +68,7 @@ exports[`should work with extensions 1`] = `
activeClassName="active"
to="/admin/custom_metrics"
>
Custom Metrics
custom_metrics.page
</IndexLink>
</li>
<li>
@@ -156,7 +156,7 @@ exports[`should work with extensions 1`] = `
activeClassName="active"
to="/admin/projects_management"
>
Management
management
</IndexLink>
</li>
<li>

+ 4
- 2
server/sonar-web/src/main/js/apps/account/notifications/Projects.js View File

@@ -123,7 +123,9 @@ class Projects extends React.PureComponent {
{allProjects.map(project => <ProjectNotifications key={project.key} project={project} />)}

<div className="spacer-top panel bg-muted">
<span className="text-middle spacer-right">Set notifications for:</span>
<span className="text-middle spacer-right">
{translate('my_account.set_notifications_for')}:
</span>
<Select.Async
autoload={false}
cache={false}
@@ -133,7 +135,7 @@ class Projects extends React.PureComponent {
minimumInput={2}
optionRenderer={this.renderOption}
onChange={this.handleAddProject}
placeholder="Search Project"
placeholder={translate('my_account.search_project')}
/>
</div>
</section>

+ 9
- 6
server/sonar-web/src/main/js/apps/account/notifications/__tests__/__snapshots__/Projects-test.js.snap View File

@@ -29,7 +29,8 @@ exports[`should render projects 1`] = `
<span
className="text-middle spacer-right"
>
Set notifications for:
my_account.set_notifications_for
:
</span>
<Async
autoload={false}
@@ -43,7 +44,7 @@ exports[`should render projects 1`] = `
onChange={[Function]}
optionRenderer={[Function]}
options={Array []}
placeholder="Search Project"
placeholder="my_account.search_project"
searchPromptText="Type to search"
style={
Object {
@@ -92,7 +93,8 @@ exports[`should render projects 2`] = `
<span
className="text-middle spacer-right"
>
Set notifications for:
my_account.set_notifications_for
:
</span>
<Async
autoload={false}
@@ -106,7 +108,7 @@ exports[`should render projects 2`] = `
onChange={[Function]}
optionRenderer={[Function]}
options={Array []}
placeholder="Search Project"
placeholder="my_account.search_project"
searchPromptText="Type to search"
style={
Object {
@@ -155,7 +157,8 @@ exports[`should render projects 3`] = `
<span
className="text-middle spacer-right"
>
Set notifications for:
my_account.set_notifications_for
:
</span>
<Async
autoload={false}
@@ -169,7 +172,7 @@ exports[`should render projects 3`] = `
onChange={[Function]}
optionRenderer={[Function]}
options={Array []}
placeholder="Search Project"
placeholder="my_account.search_project"
searchPromptText="Type to search"
style={
Object {

+ 3
- 2
server/sonar-web/src/main/js/apps/account/profile/Profile.js View File

@@ -24,6 +24,7 @@ import UserExternalIdentity from './UserExternalIdentity';
import UserGroups from './UserGroups';
import UserScmAccounts from './UserScmAccounts';
import { getCurrentUser, areThereCustomOrganizations } from '../../../store/rootReducer';
import { translate } from '../../../helpers/l10n';

/*::
type Props = {
@@ -45,7 +46,7 @@ function Profile(props /*: Props */) {
return (
<div className="account-body account-container">
<div className="spacer-bottom">
Login: <strong id="login">{user.login}</strong>
{translate('login')}: <strong id="login">{user.login}</strong>
</div>

{!user.local &&
@@ -57,7 +58,7 @@ function Profile(props /*: Props */) {

{!!user.email && (
<div className="spacer-bottom">
Email: <strong id="email">{user.email}</strong>
{translate('my_profile.email')}: <strong id="email">{user.email}</strong>
</div>
)}


+ 11
- 13
server/sonar-web/src/main/js/apps/account/templates/account-tokens.hbs View File

@@ -1,4 +1,4 @@
<h2 class="spacer-bottom">Tokens</h2>
<h2 class="spacer-bottom">{{t 'users.tokens'}}</h2>

<div class="big-spacer-bottom big-spacer-right markdown">
<p>{{t 'my_account.tokens_description'}}</p>
@@ -8,8 +8,8 @@
<table class="data">
<thead>
<tr>
<th>Name</th>
<th class="text-right">Created</th>
<th>{{t 'name'}}</th>
<th class="text-right">{{t 'created'}}</th>
<th>&nbsp;</th>
</tr>
</thead>
@@ -28,9 +28,9 @@
<div class="big-spacer-left">
<form class="js-revoke-token-form" data-token="{{name}}">
{{#if deleting}}
<button class="button-red active input-small">Sure?</button>
<button class="button-red active input-small">{{t 'users.tokens.sure'}}</button>
{{else}}
<button class="button-red input-small">Revoke</button>
<button class="button-red input-small">{{t 'users.tokens.revoke'}}</button>
{{/if}}
</form>
</div>
@@ -39,7 +39,7 @@
{{else}}
<tr>
<td colspan="3">
<span class="note">No tokens</span>
<span class="note">{{t 'users.no_tokens'}}</span>
</td>
</tr>
{{/each}}
@@ -52,23 +52,21 @@
{{/each}}

<form class="js-generate-token-form spacer-top panel bg-muted">
<label>Generate New Token:</label>
<input type="text" required maxlength="100" placeholder="Enter Token Name">
<button>Generate</button>
<label>{{t 'users.generate_new_token'}}:</label>
<input type="text" required maxlength="100" placeholder="{{t 'users.enter_token_name'}}">
<button>{{t 'users.generate'}}</button>
</form>

{{#if newToken}}
<div class="panel panel-white big-spacer-top">
<div class="alert alert-warning">
New token "{{limitString newToken.name}}" has been created. Make sure you copy it now, you won’t be able to see it
again!
{{tp 'users.tokens.new_token_created' newToken.name}}
</div>

<table class="data">
<tr>

<td class="thin">
<button class="js-copy-to-clipboard" data-clipboard-text="{{newToken.token}}">Copy</button>
<button class="js-copy-to-clipboard" data-clipboard-text="{{newToken.token}}">{{t 'copy'}}</button>
</td>
<td class="nowrap">
<div class="monospaced text-success">{{newToken.token}}</div>

+ 6
- 1
server/sonar-web/src/main/js/apps/account/tokens-view.js View File

@@ -22,6 +22,7 @@ import Marionette from 'backbone.marionette';
import Clipboard from 'clipboard';
import Template from './templates/account-tokens.hbs';
import { getTokens, generateToken, revokeToken } from '../../api/user-tokens';
import { translate } from '../../helpers/l10n';

export default Marionette.ItemView.extend({
template: Template,
@@ -81,7 +82,11 @@ export default Marionette.ItemView.extend({
const clipboard = new Clipboard(copyButton.get(0));
clipboard.on('success', () => {
copyButton
.tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' })
.tooltip({
title: translate('users.tokens.copied'),
placement: 'bottom',
trigger: 'manual'
})
.tooltip('show');
setTimeout(() => copyButton.tooltip('hide'), 1000);
});

+ 3
- 2
server/sonar-web/src/main/js/apps/background-tasks/components/DateFilter.js View File

@@ -20,6 +20,7 @@
import $ from 'jquery';
import React, { Component } from 'react';
import { isValidDate, parseDate, toShortNotSoISOString } from '../../../helpers/dates';
import { translate } from '../../../helpers/l10n';

export default class DateFilter extends Component {
componentDidMount() {
@@ -70,7 +71,7 @@ export default class DateFilter extends Component {
onChange={() => true}
ref="minDate"
type="text"
placeholder="From"
placeholder={translate('from')}
/>{' '}
<input
className="input-small"
@@ -78,7 +79,7 @@ export default class DateFilter extends Component {
onChange={() => true}
ref="maxDate"
type="text"
placeholder="To"
placeholder={translate('to')}
/>
</div>
);

+ 10
- 6
server/sonar-web/src/main/js/apps/background-tasks/components/Search.js View File

@@ -79,7 +79,9 @@ export default class Search extends React.PureComponent {

return (
<li>
<h6 className="bt-search-form-label">Search by Task or Component</h6>
<h6 className="bt-search-form-label">
{translate('background_tasks.search_by_task_or_component')}
</h6>

<input
onChange={e => this.handleQueryChange(e.target.value)}
@@ -87,7 +89,7 @@ export default class Search extends React.PureComponent {
ref="searchInput"
className="js-search input-medium"
type="search"
placeholder="Search"
placeholder={translate('search_verb')}
/>
</li>
);
@@ -109,12 +111,12 @@ export default class Search extends React.PureComponent {
<section className="big-spacer-top big-spacer-bottom">
<ul className="bt-search-form">
<li>
<h6 className="bt-search-form-label">Status</h6>
<h6 className="bt-search-form-label">{translate('status')}</h6>
<StatusFilter value={status} onChange={this.handleStatusChange.bind(this)} />
</li>
{types.length > 1 && (
<li>
<h6 className="bt-search-form-label">Type</h6>
<h6 className="bt-search-form-label">{translate('type')}</h6>
<TypesFilter
value={taskType}
types={types}
@@ -124,12 +126,14 @@ export default class Search extends React.PureComponent {
)}
{!component && (
<li>
<h6 className="bt-search-form-label">Only Latest Analysis</h6>
<h6 className="bt-search-form-label">
{translate('background_tasks.currents_filter.ONLY_CURRENTS')}
</h6>
<CurrentsFilter value={currents} onChange={this.handleCurrentsChange.bind(this)} />
</li>
)}
<li>
<h6 className="bt-search-form-label">Date</h6>
<h6 className="bt-search-form-label">{translate('date')}</h6>
<DateFilter
minSubmittedAt={minSubmittedAt}
maxExecutedAt={maxExecutedAt}

+ 4
- 0
server/sonar-web/src/main/js/apps/coding-rules/rule/rule-profile-view.js View File

@@ -76,6 +76,8 @@ export default Marionette.ItemView.extend({
'coding_rules.revert_to_parent_definition.confirm',
this.getParent().name
),
yesLabel: translate('yes'),
noLabel: translate('cancel'),
yesHandler() {
return $.ajax({
type: 'POST',
@@ -98,6 +100,8 @@ export default Marionette.ItemView.extend({
confirmDialog({
title: translate('coding_rules.deactivate'),
html: translateWithParameters('coding_rules.deactivate.confirm'),
yesLabel: translate('yes'),
noLabel: translate('cancel'),
yesHandler() {
return $.ajax({
type: 'POST',

+ 4
- 5
server/sonar-web/src/main/js/apps/coding-rules/templates/rule/coding-rules-rule-meta.hbs View File

@@ -2,8 +2,7 @@
<div class="page-actions">
<span class="note">{{key}}</span>

<a class="coding-rules-detail-permalink link-no-underline spacer-left" target="_blank" href="{{permalink}}"
data-toggle="tooltip" data-placement="left" title="Rule permalink">
<a class="coding-rules-detail-permalink link-no-underline spacer-left" target="_blank" href="{{permalink}}">
<svg
class="text-text-top"
xmlns="http://www.w3.org/2000/svg"
@@ -33,13 +32,13 @@
</li>

<li class="coding-rules-detail-property"
data-toggle="tooltip" data-placement="bottom" title="Default rule severity">
data-toggle="tooltip" data-placement="bottom" title="{{t 'default_severity'}}">
{{severityIcon severity}}&nbsp;{{t "severity" severity}}
</li>

{{#notEq status 'READY'}}
<li class="coding-rules-detail-property"
data-toggle="tooltip" data-placement="bottom" title="Rule status">
data-toggle="tooltip" data-placement="bottom" title="{{t 'status'}}">
<span class="badge badge-normal-size badge-danger-light">
{{t 'rules.status' status}}
</span>
@@ -47,7 +46,7 @@
{{/notEq}}

<li class="coding-rules-detail-property coding-rules-detail-tag-list {{#if canCustomizeRule}}coding-rules-detail-tags-change{{/if}}"
data-toggle="tooltip" data-placement="bottom" title="Rule tags">
data-toggle="tooltip" data-placement="bottom" title="{{t 'tags'}}">
<i class="icon-tags"></i>
<span>{{#if allTags}}{{join allTags ', '}}{{else}}{{t 'coding_rules.no_tags'}}{{/if}}</span>
{{#if canCustomizeRule}}<i class="icon-dropdown"></i>{{/if}}

+ 4
- 4
server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-delete.hbs View File

@@ -1,13 +1,13 @@
<form id="delete-custom-measure-form">
<div class="modal-head">
<h2>Delete Custom Measure</h2>
<h2>{{t 'custom_measures.delete_custom_measure'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
Are you sure you want to delete custom measure "{{metric.name}}"?
{{tp 'custom_measures.delete_custom_measure.confirmation' metric.name}}
</div>
<div class="modal-foot">
<button id="delete-custom-measure-submit" class="button-red">Delete</button>
<a href="#" class="js-modal-close" id="delete-custom-measure-cancel">Cancel</a>
<button id="delete-custom-measure-submit" class="button-red">{{t 'delete'}}</button>
<a href="#" class="js-modal-close" id="delete-custom-measure-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 6
- 6
server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-form.hbs View File

@@ -1,6 +1,6 @@
<form id="create-custom-measure-form" autocomplete="off">
<div class="modal-head">
<h2>{{#if id}}Update{{else}}Create{{/if}} Custom Measure</h2>
<h2>{{#if id}}{{t 'custom_measures.update_custom_measure'}}{{else}}{{t 'custom_measures.create_custom_measure'}}{{/if}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
@@ -8,7 +8,7 @@
{{#unless id}}
{{#if canCreateMetric}}
<div class="modal-field">
<label for="create-custom-measure-metric">Metric<em class="mandatory">*</em></label>
<label for="create-custom-measure-metric">{{t 'custom_measures.metric'}}<em class="mandatory">*</em></label>
<select id="create-custom-measure-metric" name="metric" required>
{{#each metrics}}
<option value="{{id}}" {{#eq id ../metric.id}}selected{{/eq}}>{{name}}</option>
@@ -21,19 +21,19 @@
{{/unless}}

<div class="modal-field">
<label for="create-custom-measure-value">Value<em class="mandatory">*</em></label>
<label for="create-custom-measure-value">{{t 'value'}}<em class="mandatory">*</em></label>
<input id="create-custom-measure-value" name="value" type="text" maxlength="200" required value="{{value}}">
</div>

<div class="modal-field">
<label for="create-custom-measure-description">Description</label>
<label for="create-custom-measure-description">{{t 'description'}}</label>
<textarea id="create-custom-measure-description" name="description">{{description}}</textarea>
</div>
</div>
<div class="modal-foot">
<button id="create-custom-measure-submit" {{#unless canCreateMetric}}disabled{{/unless}}>
{{#if id}}Update{{else}}Create{{/if}}
{{#if id}}{{t 'update_verb'}}{{else}}{{t 'create_verb'}}{{/if}}
</button>
<a href="#" class="js-modal-close" id="create-custom-measure-cancel">Cancel</a>
<a href="#" class="js-modal-close" id="create-custom-measure-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 2
- 2
server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-list-footer.hbs View File

@@ -1,6 +1,6 @@
<footer class="spacer-top note text-center">
{{count}}/{{total}} shown
{{tp 'x_of_y_shown' count total}}
{{#if more}}
<a id="custom-measures-fetch-more" class="spacer-left" href="#">show more</a>
<a id="custom-measures-fetch-more" class="spacer-left" href="#">{{t 'show_more'}}</a>
{{/if}}
</footer>

+ 4
- 4
server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-list-item.hbs View File

@@ -20,15 +20,15 @@

<td class="">
{{#if updatedAt }}
Updated on <span class="js-custom-measure-created-at">{{d updatedAt}}</span>
{{t 'updated_on'}} <span class="js-custom-measure-created-at">{{d updatedAt}}</span>
{{else}}
{{#if createdAt }}
Created on <span class="js-custom-measure-created-at">{{d createdAt}}</span>
{{t 'created_on'}} <span class="js-custom-measure-created-at">{{d createdAt}}</span>
{{else}}
Created
{{t 'created'}}
{{/if}}
{{/if}}
by <span class="js-custom-measure-user">{{user.name}}</span>
{{t 'by_'}} <span class="js-custom-measure-user">{{user.name}}</span>
</td>

<td class="thin nowrap">

+ 4
- 4
server/sonar-web/src/main/js/apps/custom-measures/templates/custom-measures-list.hbs View File

@@ -1,10 +1,10 @@
<table class="data zebra">
<thead>
<tr>
<th>Metric</th>
<th>Value</th>
<th>Description</th>
<th>Date</th>
<th>{{t 'custom_measures.metric'}}</th>
<th>{{t 'value'}}</th>
<th>{{t 'description'}}</th>
<th>{{t 'date'}}</th>
<th>&nbsp;</th>
</tr>
</thead>

+ 4
- 4
server/sonar-web/src/main/js/apps/groups/templates/groups-delete.hbs View File

@@ -1,13 +1,13 @@
<form id="delete-group-form" autocomplete="off">
<div class="modal-head">
<h2>Delete Group</h2>
<h2>{{t 'groups.delete_group'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
<div class="js-modal-text">Are you sure you want to delete "{{name}}"?</div>
<div class="js-modal-text">{{tp 'groups.delete_group.confirmation' name}}</div>
</div>
<div class="modal-foot">
<button id="delete-group-submit">Delete</button>
<a href="#" class="js-modal-close" id="delete-group-cancel">Cancel</a>
<button id="delete-group-submit">{{t 'delete'}}</button>
<a href="#" class="js-modal-close" id="delete-group-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 5
- 5
server/sonar-web/src/main/js/apps/groups/templates/groups-form.hbs View File

@@ -1,24 +1,24 @@
<form id="create-group-form" autocomplete="off">
<div class="modal-head">
<h2>{{#if id}}Update{{else}}Create{{/if}} Group</h2>
<h2>{{#if id}}{{t 'groups.update_group'}}{{else}}{{t 'groups.create_group'}}{{/if}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
<div class="modal-field">
<label for="create-group-name">Name<em class="mandatory">*</em></label>
<label for="create-group-name">{{t 'name'}}<em class="mandatory">*</em></label>
{{! keep this fake field to hack browser autofill }}
<input id="create-group-name-fake" name="name-fake" type="text" class="hidden">
<input id="create-group-name" name="name" type="text" size="50" maxlength="255" required value="{{name}}">
</div>
<div class="modal-field">
<label for="create-group-description">Description</label>
<label for="create-group-description">{{t 'description'}}</label>
{{! keep this fake field to hack browser autofill }}
<textarea id="create-group-description-fake" name="description-fake" class="hidden"></textarea>
<textarea id="create-group-description" name="description">{{description}}</textarea>
</div>
</div>
<div class="modal-foot">
<button id="create-group-submit">{{#if id}}Update{{else}}Create{{/if}}</button>
<a href="#" class="js-modal-close" id="create-group-cancel">Cancel</a>
<button id="create-group-submit">{{#if id}}{{t 'update_verb'}}{{else}}{{t 'create'}}{{/if}}</button>
<a href="#" class="js-modal-close" id="create-group-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 1
- 1
server/sonar-web/src/main/js/apps/groups/templates/groups-header.hbs View File

@@ -3,7 +3,7 @@
<i class="spinner hidden"></i>
<div class="page-actions">
<div class="button-group">
<button id="groups-create">Create Group</button>
<button id="groups-create">{{t 'groups.create_group'}}</button>
</div>
</div>
<p class="page-description">{{t 'user_groups.page.description'}}</p>

+ 2
- 2
server/sonar-web/src/main/js/apps/groups/templates/groups-list-footer.hbs View File

@@ -1,6 +1,6 @@
<footer class="spacer-top note text-center">
{{count}}/{{total}} shown
{{tp 'x_of_y_shown' count total}}
{{#if more}}
<a id="groups-fetch-more" class="spacer-left" href="#">show more</a>
<a id="groups-fetch-more" class="spacer-left" href="#">{{t 'show_more'}}</a>
{{/if}}
</footer>

+ 3
- 3
server/sonar-web/src/main/js/apps/groups/templates/groups-list-item.hbs View File

@@ -1,7 +1,7 @@
<div class="pull-right big-spacer-left nowrap">
{{#unless default}}
<a class="js-group-update icon-edit little-spacer-right" title={{t 'users.update_details'}} data-toggle="tooltip" href="#"></a>
<a class="js-group-delete icon-delete" title={{t 'delete'}} data-toggle="tooltip" href="#"></a>
<a class="js-group-update icon-edit little-spacer-right" title="{{t 'update_details'}}" data-toggle="tooltip" href="#"></a>
<a class="js-group-delete icon-delete" title="{{t 'delete'}}" data-toggle="tooltip" href="#"></a>
{{/unless}}
</div>

@@ -19,7 +19,7 @@
<div class="overflow-hidden bordered-left">
<span class="spacer-left spacer-right">{{membersCount}}</span>
{{#unless default}}
<a class="js-group-users icon-bullet-list" title={{t 'users.update'}} data-toggle="tooltip" href="#"></a>
<a class="js-group-users icon-bullet-list" title="{{t 'users.update'}}" data-toggle="tooltip" href="#"></a>
{{/unless}}
</div>
</div>

+ 1
- 1
server/sonar-web/src/main/js/apps/groups/templates/groups-list.hbs View File

@@ -2,7 +2,7 @@
{{#isNull organization}}
<div class="panel panel-vertical js-anyone">
<div class="display-inline-block text-top width-20">
<strong class="js-group-name">Anyone</strong>
<strong class="js-group-name">{{t 'groups.anyone'}}</strong>
</div>

<div class="display-inline-block text-top big-spacer-left width-25">

+ 1
- 1
server/sonar-web/src/main/js/apps/groups/templates/groups-search.hbs View File

@@ -1,6 +1,6 @@
<div class="panel panel-vertical bordered-bottom spacer-bottom">
<form id="groups-search-form" class="search-box">
<button id="groups-search-submit" class="search-box-submit button-clean"><i class="icon-search"></i></button>
<input id="groups-search-query" class="search-box-input" type="search" name="q" placeholder="Search" maxlength="100">
<input id="groups-search-query" class="search-box-input" type="search" name="q" placeholder="{{t 'search_verb'}}" maxlength="100">
</form>
</div>

+ 2
- 2
server/sonar-web/src/main/js/apps/groups/templates/groups-users.hbs View File

@@ -1,10 +1,10 @@
<div class="modal-head">
<h2>Update users</h2>
<h2>{{t 'users.update'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
<div id="groups-users"></div>
</div>
<div class="modal-foot">
<a href="#" class="js-modal-close" id="groups-users-done">Done</a>
<a href="#" class="js-modal-close" id="groups-users-done">{{t 'Done'}}</a>
</div>

+ 2
- 2
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-failed.hbs View File

@@ -1,2 +1,2 @@
<h1 class="maintenance-title text-danger">Upgrade Failed</h1>
<p class="maintenance-text">Database connection cannot be established. Please check database status and JDBC settings.</p>
<h1 class="maintenance-title text-danger">{{t 'maintenance.upgrade_failed'}}</h1>
<p class="maintenance-text">{{t 'maintenance.upgrade_failed.text'}}</p>

+ 2
- 2
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-not-supported.hbs View File

@@ -1,2 +1,2 @@
<h1 class="maintenance-title text-danger">Migration not supported</h1>
<p>Migration is not supported on embedded databases.</p>
<h1 class="maintenance-title text-danger">{{t 'maintenance.migration_not_supported'}}</h1>
<p>{{t 'maintenance.migration_not_supported.text'}}</p>

+ 5
- 5
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-required.hbs View File

@@ -1,7 +1,7 @@
<h1 class="maintenance-title">Upgrade Database</h1>
<p class="maintenance-text">The database upgrade can take several minutes.</p>
<p class="maintenance-text">It is mandatory to <strong>back up database</strong> before upgrading.</p>
<p class="maintenance-text">Make sure you have followed the steps from the <a target="_blank" href="https://redirect.sonarsource.com/doc/upgrading.html">SonarQube Upgrade guide</a>.</p>
<h1 class="maintenance-title">{{t 'maintenance.upgrade_database'}}</h1>
<p class="maintenance-text">{{t 'maintenance.upgrade_database.1'}}</p>
<p class="maintenance-text">{{t 'maintenance.upgrade_database.2'}}</p>
<p class="maintenance-text">{{t 'maintenance.upgrade_database.3'}}</p>
<div class="maintenance-spinner">
<button id="start-migration">Upgrade</button>
<button id="start-migration">{{t 'maintenance.upgrade'}}</button>
</div>

+ 2
- 2
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-running.hbs View File

@@ -1,10 +1,10 @@
<h1 class="maintenance-title">Database Migration</h1>
<h1 class="maintenance-title">{{t 'maintenance.database_migration'}}</h1>
{{#if message}}
<p class="maintenance-text text-center">{{message}}</p>
{{/if}}
{{#if startedAt}}
<p class="maintenance-text text-center">
Started {{fromNow startedAt}}<br>
{{t 'background_tasks.table.started'}} {{fromNow startedAt}}<br>
<small class="text-muted">{{dt startedAt}}</small>
</p>
{{/if}}

+ 2
- 2
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-migration-succeeded.hbs View File

@@ -1,4 +1,4 @@
<h1 class="maintenance-title text-success">Database is up-to-date</h1>
<h1 class="maintenance-title text-success">{{t 'maintenance.database_is_up_to_date'}}</h1>
<p class="maintenance-text text-center">
<a href="{{link '/'}}">Home</a>
<a href="{{link '/'}}">{{t 'layout.home'}}</a>
</p>

+ 2
- 2
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-state-no-migration.hbs View File

@@ -1,4 +1,4 @@
<h1 class="maintenance-title">Database is up-to-date</h1>
<h1 class="maintenance-title">{{t 'maintenance.database_is_up_to_date'}}</h1>
<p class="maintenance-text text-center">
<a href="{{link '/'}}">Home</a>
<a href="{{link '/'}}">{{t 'layout.home'}}</a>
</p>

+ 3
- 3
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-down.hbs View File

@@ -1,5 +1,5 @@
<h1 class="maintenance-title text-danger">SonarQube is down</h1>
<p class="maintenance-text">Something went wrong. Please contact your system administrator.</p>
<h1 class="maintenance-title text-danger">{{t 'maintenance.sonarqube_is_down'}}</h1>
<p class="maintenance-text">{{t 'maintenance.sonarqube_is_down.text'}}</p>
<p class="maintenance-text text-center">
<a href="{{link '/'}}">Try Again</a>
<a href="{{link '/'}}">{{t 'maintenance.try_again'}}</a>
</p>

+ 3
- 7
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-migration.hbs View File

@@ -1,7 +1,3 @@
<h1 class="maintenance-title">SonarQube is under maintenance</h1>
<p class="maintenance-text">While waiting, you might want to investigate
<a href="https://redirect.sonarsource.com/doc/plugin-library.html">new plugins</a> to extend the current functionality.
</p>
<p class="maintenance-text">If you are an administrator and have no idea why this message is being shown, you should
read the <a href="https://redirect.sonarsource.com/doc/upgrading.html">upgrade guide</a>.
</p>
<h1 class="maintenance-title">{{t 'maintenance.sonarqube_is_under_maintenance'}}</h1>
<p class="maintenance-text">{{{t 'maintenance.sonarqube_is_under_maintenance.1'}}}</p>
<p class="maintenance-text">{{{t 'maintenance.sonarqube_is_under_maintenance.2'}}}</p>

+ 1
- 1
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-starting.hbs View File

@@ -1,2 +1,2 @@
<h1 class="maintenance-title">SonarQube is starting</h1>
<h1 class="maintenance-title">{{t 'maintenance.sonarqube_is_starting'}}</h1>
<p class="maintenance-spinner"><i class="spinner"></i></p>

+ 3
- 3
server/sonar-web/src/main/js/apps/maintenance/templates/_maintenance-status-up.hbs View File

@@ -1,5 +1,5 @@
<h1 class="maintenance-title">SonarQube is up</h1>
<p class="maintenance-text text-center">All systems operational.</p>
<h1 class="maintenance-title">{{t 'maintenance.sonarqube_is_up'}}</h1>
<p class="maintenance-text text-center">{{t 'maintenance.all_systems_opetational'}}</p>
<p class="maintenance-text text-center">
<a href="{{link '/'}}">Home</a>
<a href="{{link '/'}}">{{t 'layout.home'}}</a>
</p>

+ 4
- 4
server/sonar-web/src/main/js/apps/metrics/templates/metrics-delete.hbs View File

@@ -1,13 +1,13 @@
<form id="delete-metric-form">
<div class="modal-head">
<h2>Delete Metric</h2>
<h2>{{t 'custom_metrics.delete_metric'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
Are you sure you want to delete metric "{{name}}"?
{{tp 'custom_metrics.delete_metric.confirmation' name}}
</div>
<div class="modal-foot">
<button id="delete-metric-submit" class="button-red">Delete</button>
<a href="#" class="js-modal-close" id="delete-metric-cancel">Cancel</a>
<button id="delete-metric-submit" class="button-red">{{t 'delete'}}</button>
<a href="#" class="js-modal-close" id="delete-metric-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 8
- 8
server/sonar-web/src/main/js/apps/metrics/templates/metrics-form.hbs View File

@@ -1,27 +1,27 @@
<form id="create-metric-form" autocomplete="off">
<div class="modal-head">
<h2>{{#if id}}Update{{else}}Create{{/if}} Metric</h2>
<h2>{{#if id}}{{t 'custom_metrics.update_metric'}}{{else}}{{t 'custom_metrics.create_metric'}}{{/if}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
<div class="modal-field">
<label for="create-metric-key">Key<em class="mandatory">*</em></label>
<label for="create-metric-key">{{t 'key'}}<em class="mandatory">*</em></label>
<input id="create-metric-key" name="key" type="text" maxlength="200" required value="{{key}}">
</div>
<div class="modal-field">
<label for="create-metric-name">Name<em class="mandatory">*</em></label>
<label for="create-metric-name">{{t 'name'}}<em class="mandatory">*</em></label>
<input id="create-metric-name" name="name" type="text" maxlength="200" required value="{{name}}">
</div>
<div class="modal-field">
<label for="create-metric-description">Description</label>
<label for="create-metric-description">{{t 'description'}}</label>
<textarea id="create-metric-description" name="description">{{description}}</textarea>
</div>
<div class="modal-field">
<label for="create-metric-domain">Domain</label>
<label for="create-metric-domain">{{t 'custom_metrics.domain'}}</label>
<input id="create-metric-domain" name="domain" type="text" maxlength="200" value="{{this.domain}}">
</div>
<div class="modal-field">
<label for="create-metric-type">Type<em class="mandatory">*</em></label>
<label for="create-metric-type">{{t 'type'}}<em class="mandatory">*</em></label>
<select id="create-metric-type" name="type">
{{#each types}}
<option value="{{this}}" {{#eq this ../type}}selected{{/eq}}>{{t 'metric.type' this}}</option>
@@ -30,7 +30,7 @@
</div>
</div>
<div class="modal-foot">
<button id="create-metric-submit">{{#if id}}Update{{else}}Create{{/if}}</button>
<a href="#" class="js-modal-close" id="create-metric-cancel">Cancel</a>
<button id="create-metric-submit">{{#if id}}{{t 'update_verb'}}{{else}}{{t 'create'}}{{/if}}</button>
<a href="#" class="js-modal-close" id="create-metric-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 3
- 4
server/sonar-web/src/main/js/apps/metrics/templates/metrics-header.hbs View File

@@ -1,10 +1,9 @@
<header class="page-header">
<h1 class="page-title">Custom Metrics</h1>
<h1 class="page-title">{{t 'custom_metrics.page'}}</h1>
<div class="page-actions">
<div class="button-group">
<button id="metrics-create">Create Metric</button>
<button id="metrics-create">{{t 'custom_metrics.create_metric'}}</button>
</div>
</div>
<p class="page-description">These metrics are available for all projects. Manual measures can be set at project level
via the configuration interface.</p>
<p class="page-description">{{t 'custom_metrics.page.description'}}</p>
</header>

+ 2
- 2
server/sonar-web/src/main/js/apps/metrics/templates/metrics-list-footer.hbs View File

@@ -1,6 +1,6 @@
<footer class="spacer-top note text-center">
{{count}}/{{total}} shown
{{tp 'x_of_y_shown' count total}}
{{#if more}}
<a id="metrics-fetch-more" class="spacer-left" href="#">show more</a>
<a id="metrics-fetch-more" class="spacer-left" href="#">{{t 'show_more'}}</a>
{{/if}}
</footer>

+ 2
- 2
server/sonar-web/src/main/js/apps/metrics/templates/metrics-list-item.hbs View File

@@ -1,6 +1,6 @@
<div class="pull-right big-spacer-left nowrap">
<a class="js-metric-update icon-edit" title="Update" data-toggle="tooltip" href="#"></a>
<a class="js-metric-delete icon-delete" title="Delete" data-toggle="tooltip" href="#"></a>
<a class="js-metric-update icon-edit" title="{{t 'update_verb'}}" data-toggle="tooltip" href="#"></a>
<a class="js-metric-delete icon-delete" title="{{t 'delete'}}" data-toggle="tooltip" href="#"></a>
</div>

<div class="display-inline-block text-top width-30">

+ 2
- 2
server/sonar-web/src/main/js/apps/overview/main/enhance.js View File

@@ -34,7 +34,7 @@ import {
getShortType,
getRatingTooltip
} from '../../../helpers/measures';
import { translateWithParameters } from '../../../helpers/l10n';
import { translateWithParameters, getLocalizedMetricName } from '../../../helpers/l10n';
import { getPeriodDate } from '../../../helpers/periods';
import {
getComponentDrilldownUrl,
@@ -93,7 +93,7 @@ export default function enhance(ComposedComponent) {
</div>

<div className="overview-domain-measure-label offset-left">
{measure.metric.name}
{getLocalizedMetricName(measure.metric)}
{this.renderHistoryLink(measure.metric.key)}
</div>
</div>

+ 2
- 2
server/sonar-web/src/main/js/apps/permission-templates/components/ActionsCell.js View File

@@ -162,7 +162,7 @@ export default class ActionsCell extends React.PureComponent {
<li>
<Link to={{ pathname, query: { id: t.id } }}>
{this.renderDropdownIcon(<i className="icon-edit" />)}
Edit Permissions
{translate('edit_permissions')}
</Link>
</li>
)}
@@ -170,7 +170,7 @@ export default class ActionsCell extends React.PureComponent {
<li>
<a href="#" className="js-update" onClick={this.handleUpdateClick.bind(this)}>
{this.renderDropdownIcon(<i className="icon-edit" />)}
Update Details
{translate('update_details')}
</a>
</li>


+ 2
- 2
server/sonar-web/src/main/js/apps/permission-templates/components/Defaults.js View File

@@ -20,7 +20,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { sortBy } from 'lodash';
import { translate } from '../../../helpers/l10n';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { PermissionTemplateType } from '../propTypes';

export default class Defaults extends React.PureComponent {
@@ -42,7 +42,7 @@ export default class Defaults extends React.PureComponent {
return (
<div>
<span className="badge spacer-right">
{translate('default')} for {qualifiers}
{translateWithParameters('permission_template.default_for', qualifiers)}
</span>
</div>
);

+ 3
- 3
server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js View File

@@ -31,19 +31,19 @@ export default class ListHeader extends React.PureComponent {
renderTooltip = permission =>
permission.key === 'user' || permission.key === 'codeviewer' ? (
<div>
{permission.description}
{translate('projects_role', permission.key, 'desc')}
<div className="alert alert-warning spacer-top">
{translate('projects_role.public_projects_warning')}
</div>
</div>
) : (
permission.description
translate('projects_role', permission.key, 'desc')
);

render() {
const cells = this.props.permissions.map(permission => (
<th key={permission.key} className="permission-column">
{permission.name}
{translate('projects_role', permission.key)}
<Tooltip overlay={this.renderTooltip(permission)}>
<i className="icon-help little-spacer-left" />
</Tooltip>

+ 4
- 12
server/sonar-web/src/main/js/apps/permission-templates/components/__tests__/__snapshots__/Defaults-test.js.snap View File

@@ -5,9 +5,7 @@ exports[`should render one qualifier 1`] = `
<span
className="badge spacer-right"
>
default
for
qualifiers.DEV
permission_template.default_for.qualifiers.DEV
</span>
</div>
`;
@@ -17,9 +15,7 @@ exports[`should render only projects for custom organization 1`] = `
<span
className="badge spacer-right"
>
default
for
qualifiers.TRK
permission_template.default_for.qualifiers.TRK
</span>
</div>
`;
@@ -29,9 +25,7 @@ exports[`should render several qualifiers 1`] = `
<span
className="badge spacer-right"
>
default
for
qualifiers.TRK, qualifiers.VW
permission_template.default_for.qualifiers.TRK, qualifiers.VW
</span>
</div>
`;
@@ -41,9 +35,7 @@ exports[`should render several qualifiers for default organization 1`] = `
<span
className="badge spacer-right"
>
default
for
qualifiers.TRK, qualifiers.VW
permission_template.default_for.qualifiers.TRK, qualifiers.VW
</span>
</div>
`;

+ 4
- 4
server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-delete.hbs View File

@@ -1,13 +1,13 @@
<form id="delete-permission-template-form">
<div class="modal-head">
<h2>Delete Permission Template</h2>
<h2>{{t 'permission_template.delete_confirm_title'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
Are you sure you want to delete permission template "{{name}}"?
{{tp 'permission_template.do_you_want_to_delete_template_xxx' name}}
</div>
<div class="modal-foot">
<button id="delete-permission-template-submit" class="button-red">Delete</button>
<a href="#" class="js-modal-close" id="delete-permission-template-cancel">Cancel</a>
<button id="delete-permission-template-submit" class="button-red">{{t 'delete'}}</button>
<a href="#" class="js-modal-close" id="delete-permission-template-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 8
- 8
server/sonar-web/src/main/js/apps/permission-templates/templates/permission-templates-form.hbs View File

@@ -1,34 +1,34 @@
<form id="permission-template-form" autocomplete="off">
<div class="modal-head">
<h2>{{#if id}}Update{{else}}Create{{/if}} Permission Template</h2>
<h2>{{#if id}}{{t 'permission_template.edit_template'}}{{else}}{{t 'permission_template.new_template'}}{{/if}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>

<div class="modal-field">
<label for="permission-template-name">Name<em class="mandatory">*</em></label>
<label for="permission-template-name">{{t 'name'}}<em class="mandatory">*</em></label>
<input id="permission-template-name" name="name" type="text" maxlength="256" required value="{{name}}">
<div class="modal-field-description">
Should be unique.
{{t 'should_be_unique'}}
</div>
</div>

<div class="modal-field">
<label for="permission-template-description">Description</label>
<label for="permission-template-description">{{t 'description'}}</label>
<textarea id="permission-template-description" name="description" maxlength="4000" rows="5">{{description}}</textarea>
</div>

<div class="modal-field">
<label for="permission-template-project-key-pattern">Project Key Pattern</label>
<label for="permission-template-project-key-pattern">{{t 'permission_template.key_pattern'}}</label>
<input id="permission-template-project-key-pattern" name="keyPattern" type="text" maxlength="500"
value="{{projectKeyPattern}}">
<div class="modal-field-description">
Should be a valid regular expression.
{{t 'permission_template.key_pattern.description'}}
</div>
</div>
</div>
<div class="modal-foot">
<button id="permission-template-submit">{{#if id}}Update{{else}}Create{{/if}}</button>
<a href="#" class="js-modal-close" id="permission-template-cancel">Cancel</a>
<button id="permission-template-submit">{{#if id}}{{t 'update_verb'}}{{else}}{{t 'create'}}{{/if}}</button>
<a href="#" class="js-modal-close" id="permission-template-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 1
- 1
server/sonar-web/src/main/js/apps/permissions/project/components/PageHeader.js View File

@@ -75,7 +75,7 @@ export default class PageHeader extends React.PureComponent {
{canApplyPermissionTemplate && (
<div className="page-actions">
<button className="js-apply-template" onClick={this.handleApplyTemplate}>
Apply Template
{translate('projects_role.apply_template')}
</button>
</div>
)}

+ 4
- 4
server/sonar-web/src/main/js/apps/permissions/project/templates/ApplyTemplateTemplate.hbs View File

@@ -1,6 +1,6 @@
<form id="project-permissions-apply-template-form" autocomplete="off">
<div class="modal-head">
<h2>Apply Permission Template to "{{project.name}}"</h2>
<h2>{{tp 'projects_role.apply_template_to_xxx' project.name}}</h2>
</div>

<div class="modal-body">
@@ -16,7 +16,7 @@
{{#notNull permissionTemplates}}
<div class="modal-field">
<label for="project-permissions-template">
Template<em class="mandatory">*</em>
{{t 'template'}}<em class="mandatory">*</em>
</label>
<select id="project-permissions-template">
{{#each permissionTemplates}}
@@ -33,9 +33,9 @@
<div class="modal-foot">
{{#unless done}}
{{#notNull permissionTemplates}}
<button id="project-permissions-apply-template">Apply</button>
<button id="project-permissions-apply-template">{{t 'apply'}}</button>
{{/notNull}}
{{/unless}}
<a href="#" class="js-modal-close">Close</a>
<a href="#" class="js-modal-close">{{t 'close'}}</a>
</div>
</form>

+ 3
- 2
server/sonar-web/src/main/js/apps/permissions/shared/components/HoldersList.js View File

@@ -22,7 +22,7 @@ import PropTypes from 'prop-types';
import UserHolder from './UserHolder';
import GroupHolder from './GroupHolder';
import Tooltip from '../../../../components/controls/Tooltip';
import { translate } from '../../../../helpers/l10n';
import { translate, translateWithParameters } from '../../../../helpers/l10n';

export default class HoldersList extends React.PureComponent {
static propTypes = {
@@ -69,7 +69,8 @@ export default class HoldersList extends React.PureComponent {
backgroundColor: p.key === selectedPermission ? '#d9edf7' : 'transparent'
}}>
<div className="permission-column-inner">
<Tooltip overlay={`Filter by "${p.name}" permission`}>
<Tooltip
overlay={translateWithParameters('global_permissions.filter_by_x_permission', p.name)}>
<a data-key={p.key} href="#" onClick={this.handlePermissionClick}>
{p.name}
</a>

+ 3
- 3
server/sonar-web/src/main/js/apps/permissions/shared/components/SearchForm.js View File

@@ -53,9 +53,9 @@ export default class SearchForm extends React.PureComponent {
const { query, filter } = this.props;

const filterOptions = [
{ value: 'all', label: 'All' },
{ value: 'users', label: 'Users' },
{ value: 'groups', label: 'Groups' }
{ value: 'all', label: translate('all') },
{ value: 'users', label: translate('users.page') },
{ value: 'groups', label: translate('user_groups.page') }
];

return (

+ 1
- 1
server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx View File

@@ -217,7 +217,7 @@ export default class Search extends React.PureComponent<Props, State> {
ref={node => (this.input = node!)}
className="search-box-input input-medium"
type="search"
placeholder="Search"
placeholder={translate('search_verb')}
/>
</form>
</td>

+ 2
- 2
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/Search-test.tsx.snap View File

@@ -168,7 +168,7 @@ exports[`render qualifiers filter 1`] = `
<input
className="search-box-input input-medium"
onChange={[Function]}
placeholder="Search"
placeholder="search_verb"
type="search"
value=""
/>
@@ -270,7 +270,7 @@ exports[`renders 1`] = `
<input
className="search-box-input input-medium"
onChange={[Function]}
placeholder="Search"
placeholder="search_verb"
type="search"
value=""
/>

+ 2
- 2
server/sonar-web/src/main/js/apps/quality-profiles/changelog/ChangelogSearch.tsx View File

@@ -45,14 +45,14 @@ export default class ChangelogSearch extends React.PureComponent<Props> {
<DateInput
name="since"
value={this.formatDate(this.props.fromDate)}
placeholder="From"
placeholder={translate('from')}
onChange={this.props.onFromDateChange}
/>
{' — '}
<DateInput
name="to"
value={this.formatDate(this.props.toDate)}
placeholder="To"
placeholder={translate('to')}
onChange={this.props.onToDateChange}
/>
<button className="spacer-left" onClick={this.handleResetClick.bind(this)}>

+ 1
- 0
server/sonar-web/src/main/js/apps/quality-profiles/compare/ComparisonForm.tsx View File

@@ -46,6 +46,7 @@ export default class ComparisonForm extends React.PureComponent<Props> {
<Select
value={withKey}
options={options}
placeholder={translate('select_verb')}
clearable={false}
className="input-large"
onChange={this.handleChange.bind(this)}

+ 10
- 14
server/sonar-web/src/main/js/apps/settings/encryption/EncryptionForm.js View File

@@ -19,6 +19,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { translate } from '../../../helpers/l10n';

export default class EncryptionForm extends React.PureComponent {
static propTypes = {
@@ -42,9 +43,7 @@ export default class EncryptionForm extends React.PureComponent {
render() {
return (
<div id="encryption-form-container">
<div className="spacer-bottom">
Secret key is registered. You can encrypt any property value with the following form:
</div>
<div className="spacer-bottom">{translate('encryption.form_intro')}</div>

<form
id="encryption-form"
@@ -59,12 +58,13 @@ export default class EncryptionForm extends React.PureComponent {
value={this.state.value}
onChange={e => this.setState({ value: e.target.value })}
/>
<button className="spacer-left">Encrypt</button>
<button className="spacer-left">{translate('encryption.encrypt')}</button>
</form>

{this.props.encryptedValue != null && (
<div>
Encrypted Value:{' '}
{translate('encryption.encrypted_value')}
{': '}
<input
id="encrypted-value"
className="input-clear input-code input-super-large"
@@ -76,16 +76,12 @@ export default class EncryptionForm extends React.PureComponent {
)}

<div className="huge-spacer-top bordered-top">
<div className="big-spacer-top spacer-bottom">
Note that the secret key can be changed, but all the encrypted properties will have to
be updated.{' '}
<a href="https://redirect.sonarsource.com/doc/settings-encryption.html">
More information
</a>
</div>

<div
className="big-spacer-top spacer-bottom"
dangerouslySetInnerHTML={{ __html: translate('encryption.form_note') }}
/>
<form id="encryption-new-key-form" onSubmit={e => this.handleGenerateNewKey(e)}>
<button>Generate New Secret Key</button>
<button>{translate('encryption.generate_new_secret_key')}</button>
</form>
</div>
</div>

+ 12
- 32
server/sonar-web/src/main/js/apps/settings/encryption/GenerateSecretKeyForm.js View File

@@ -19,6 +19,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
import { translate } from '../../../helpers/l10n';

export default class GenerateSecretKeyForm extends React.PureComponent {
static propTypes = {
@@ -37,7 +38,7 @@ export default class GenerateSecretKeyForm extends React.PureComponent {
{this.props.secretKey != null ? (
<div>
<div className="big-spacer-bottom">
<h3 className="spacer-bottom">Secret Key</h3>
<h3 className="spacer-bottom">{translate('encryption.secret_key')}</h3>
<input
id="secret-key"
className="input-large"
@@ -47,43 +48,22 @@ export default class GenerateSecretKeyForm extends React.PureComponent {
/>
</div>

<h3 className="spacer-bottom">How To Use</h3>
<h3 className="spacer-bottom">{translate('encryption.how_to_use')}</h3>

<ul className="list-styled markdown">
<li className="spacer-bottom">
Store the secret key in the file <code>~/.sonar/sonar-secret.txt</code> of the
server. This file can be relocated by defining the property{' '}
<code>sonar.secretKeyPath</code> in <code>conf/sonar.properties</code>
</li>
<li className="spacer-bottom">
Restrict access to this file by making it readable and by owner only
</li>
<li className="spacer-bottom">
Restart the server if the property <code>sonar.secretKeyPath</code> has been set or
changed.
</li>
<li className="spacer-bottom">
Copy this file on all the machines that execute code inspection. Define the property{' '}
<code>sonar.secretKeyPath</code> on those machines if the path is not{' '}
<code>~/.sonar/sonar-secret.txt</code>.
</li>
<li>
For each property that you want to encrypt, generate the encrypted value and replace
the original value wherever it is stored (configuration files, command lines).
</li>
</ul>
<div
className="markdown"
dangerouslySetInnerHTML={{ __html: translate('encryption.how_to_use.content') }}
/>
</div>
) : (
<div>
<p className="spacer-bottom">
Secret key is required to be able to encrypt properties.{' '}
<a href="https://redirect.sonarsource.com/doc/settings-encryption.html">
More information
</a>
</p>
<p
className="spacer-bottom"
dangerouslySetInnerHTML={{ __html: translate('ecryption.secret_key_description') }}
/>

<form id="generate-secret-key-form" onSubmit={e => this.handleSubmit(e)}>
<button>Generate Secret Key</button>
<button>{translate('encryption.generate_secret_key')}s</button>
</form>
</div>
)}

+ 1
- 1
server/sonar-web/src/main/js/apps/settings/serverId/ServerIdApp.js View File

@@ -87,7 +87,7 @@ export default class ServerIdApp extends React.PureComponent {

{this.state.serverId != null && (
<div className={this.state.invalidServerId ? 'panel panel-danger' : 'panel'}>
Server ID:
{translate('property.category.server_id')}:
<input
id="server-id-result"
className="spacer-left input-large input-clear input-code"

+ 6
- 6
server/sonar-web/src/main/js/apps/update-center/templates/_update-center-plugin-actions.hbs View File

@@ -4,10 +4,10 @@
<div class="button-group">
{{#each updates}}
{{#eq status 'COMPATIBLE'}}
<button class="js-update" data-verion="{{release.version}}">Update to {{release.version}}</button>
<button class="js-update" data-verion="{{release.version}}">{{tp 'update_center.update_to_x' release.version}}</button>
{{/eq}}
{{/each}}
<button class="js-uninstall button-red">Uninstall</button>
<button class="js-uninstall button-red">{{t 'update_center.uninstall'}}</button>
</div>

{{else}}
@@ -16,13 +16,13 @@
<p class="little-spacer-bottom">
<input class="js-terms" type="checkbox" name="plugin-terms" id="plugin-terms-{{key}}">
<label for="plugin-terms-{{key}}">
I accept the
<a class="js-plugin-terms nowrap" href="{{termsAndConditionsUrl}}" target="_blank">Terms and Conditions</a>
{{t 'update_center.i_accept_the'}}
<a class="js-plugin-terms nowrap" href="{{termsAndConditionsUrl}}" target="_blank">{{t 'update_center.terms_and_conditions'}}</a>
</label>
</p>
<button class="js-install" disabled>Install</button>
<button class="js-install" disabled>{{t 'update_center.install'}}</button>
{{else}}
<button class="js-install">Install</button>
<button class="js-install">{{t 'update_center.install'}}</button>
{{/if}}

{{/if}}

+ 1
- 1
server/sonar-web/src/main/js/apps/update-center/templates/_update-center-plugin-changelog-entry.hbs View File

@@ -7,7 +7,7 @@
{{/notEq}}
<span class="js-plugin-changelog-date note spacer-right">{{d release.date}}</span>
{{#if release.changeLogUrl}}
<a class="js-plugin-changelog-link" href="{{release.changeLogUrl}}" target="_blank">Release Notes</a>
<a class="js-plugin-changelog-link" href="{{release.changeLogUrl}}" target="_blank">{{t 'update_center.release_notes'}}</a>
{{/if}}
</div>
<div class="js-plugin-changelog-description">{{{release.description}}}</div>

+ 1
- 1
server/sonar-web/src/main/js/apps/update-center/templates/update-center-footer.hbs View File

@@ -1,3 +1,3 @@
<footer class="spacer-top note text-center">
{{total}} shown
{{tp 'x_show' total}}
</footer>

+ 6
- 6
server/sonar-web/src/main/js/apps/update-center/templates/update-center-header.hbs View File

@@ -6,31 +6,31 @@
{{#any installing updating uninstalling}}
<div class="js-pending panel panel-warning big-spacer-bottom">
<div class="display-inline-block">
<p>SonarQube needs to be restarted in order to</p>
<p>{{t 'update_center.sonarqube_needs_to_be_restarted_to'}}</p>
<ul class="list-styled spacer-top">
{{#if installing}}
<li>
install
{{t 'update_center._install'}}
<strong class="big text-success little-spacer-left little-spacer-right">{{installing}}</strong> plugins
</li>
{{/if}}
{{#if updating}}
<li>
update
{{t 'update_center._update'}}
<strong class="big text-success little-spacer-left little-spacer-right">{{updating}}</strong> plugins
</li>
{{/if}}
{{#if uninstalling}}
<li>
uninstall
{{t 'update_center._uninstall'}}
<strong class="big text-danger little-spacer-left little-spacer-right">{{uninstalling}}</strong> plugins
</li>
{{/if}}
</ul>
</div>
<div class="pull-right">
<button class="js-restart">Restart</button>
<button class="js-cancel-all button-red">Revert</button>
<button class="js-restart">{{t 'update_center.restart'}}</button>
<button class="js-cancel-all button-red">{{t 'update_center.revert'}}</button>
</div>
</div>
{{/any}}

+ 1
- 1
server/sonar-web/src/main/js/apps/update-center/templates/update-center-plugin-changelog.hbs View File

@@ -1,5 +1,5 @@
<div class="bubble-popup-container">
<div class="bubble-popup-title">Changelog</div>
<div class="bubble-popup-title">{{t 'changelog'}}</div>

<ul class="js-plugin-changelog-list">
{{#each previousUpdates}}

+ 10
- 10
server/sonar-web/src/main/js/apps/update-center/templates/update-center-plugin.hbs View File

@@ -14,12 +14,12 @@
<ul>
{{#if version}}
<li class="little-spacer-bottom">
<strong class="js-plugin-installed-version">{{version}}</strong>&nbsp;installed
<strong class="js-plugin-installed-version">{{version}}</strong>&nbsp;{{t 'update_center._installed'}}
</li>
{{/if}}
{{#notEmpty updates}}
<li class="little-spacer-bottom spacer-top">
<strong>Updates:</strong>
<strong>{{t 'update_center.updates'}}:</strong>
</li>
{{#each updates}}
<li class="little-spacer-bottom">
@@ -48,7 +48,7 @@
<button class="button-link js-changelog issue-rule icon-ellipsis-h" data-idx="{{@index}}"></button>
{{#notEmpty update.requires}}
<p class="little-spacer-top">
<strong>Installing this plugin will also install</strong>: {{#each update.requires}} {{name}}{{/each}}
<strong>{{t 'update_center.installing_this_plugin_will_also_install'}}</strong>: {{#each update.requires}} {{name}}{{/each}}
</p>
{{/notEmpty}}
</div>
@@ -63,10 +63,10 @@
<li class="little-spacer-bottom">
<ul class="list-inline">
{{#if homepageUrl}}
<li><a class="js-plugin-homepage" href="{{homepageUrl}}" target="_blank">Homepage</a></li>
<li><a class="js-plugin-homepage" href="{{homepageUrl}}" target="_blank">{{t 'update_center.homepage'}}</a></li>
{{/if}}
{{#if issueTrackerUrl}}
<li><a class="js-plugin-issues" href="{{issueTrackerUrl}}" target="_blank">Issue Tracker</a></li>
<li><a class="js-plugin-issues" href="{{issueTrackerUrl}}" target="_blank">{{t 'update_center.issue_tracker'}}</a></li>
{{/if}}
</ul>
</li>
@@ -74,14 +74,14 @@

{{#if license}}
<li class="little-spacer-bottom text-limited" title="{{license}}">
Licensed under
{{t 'update_center.licensed_under'}}
<span class="js-plugin-license">{{license}}</span>
</li>
{{/if}}

{{#if organizationName}}
<li class="little-spacer-bottom">
Developed by
{{t 'update_center.developed_by'}}
{{#if organizationUrl}}
<a class="js-plugin-organization" href="{{organizationUrl}}" target="_blank">{{organizationName}}</a>
{{else}}
@@ -94,15 +94,15 @@

<td class="text-top text-right width-20">
{{#eq _status 'installing'}}
<p class="text-success">Install Pending</p>
<p class="text-success">{{t 'update_center.install_pending'}}</p>
{{/eq}}

{{#eq _status 'updating'}}
<p class="text-success">Update Pending</p>
<p class="text-success">{{t 'update_center.update_pending'}}</p>
{{/eq}}

{{#eq _status 'uninstalling'}}
<p class="text-danger">Uninstall Pending</p>
<p class="text-danger">{{t 'update_center.uninstall_pending'}}</p>
{{/eq}}

{{#eq _status 'failed'}}

+ 8
- 8
server/sonar-web/src/main/js/apps/update-center/templates/update-center-search.hbs View File

@@ -4,22 +4,22 @@
<li>
<input type="radio" name="update-center-filter" value="installed" id="update-center-filter-installed"
{{#eq state.section 'installed'}}checked{{/eq}}>
<label for="update-center-filter-installed">Installed</label>
<label for="update-center-filter-installed">{{t 'update_center.installed'}}</label>
</li>
<li>
<input type="radio" name="update-center-filter" value="updates" id="update-center-filter-updates"
{{#eq state.section 'updates'}}checked{{/eq}} {{#unless state.updateCenterActive}}disabled{{/unless}}>
<label for="update-center-filter-updates"
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="Update Center is not activated."{{/unless}}>
Updates Only
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="{{t 'update_center.not_activated'}}"{{/unless}}>
{{t 'update_center.updates_only'}}
</label>
</li>
<li>
<input type="radio" name="update-center-filter" value="available" id="update-center-filter-available"
{{#eq state.section 'available'}}checked{{/eq}} {{#unless state.updateCenterActive}}disabled{{/unless}}>
<label for="update-center-filter-available"
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="Update Center is not activated."{{/unless}}>
Available
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="{{t 'update_center.not_activated'}}"{{/unless}}>
{{t 'update_center.available'}}
</label>
</li>
</ul>
@@ -29,8 +29,8 @@
<input type="radio" name="update-center-filter" value="system" id="update-center-filter-system"
{{#eq state.section 'system'}}checked{{/eq}} {{#unless state.updateCenterActive}}disabled{{/unless}}>
<label for="update-center-filter-system"
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="Update Center is not activated."{{/unless}}>
System Upgrades
{{#unless state.updateCenterActive}}data-toggle="tooltip" title="{{t 'update_center.not_activated'}}"{{/unless}}>
{{t 'update_center.system_upgrades'}}
</label>
</li>
</ul>
@@ -40,7 +40,7 @@
<form id="update-center-search-form" class="search-box display-inline-block text-top">
<button id="update-center-search-submit" class="search-box-submit button-clean"><i class="icon-search"></i>
</button>
<input id="update-center-search-query" class="search-box-input" type="search" name="q" placeholder="Search"
<input id="update-center-search-query" class="search-box-input" type="search" name="q" placeholder="{{t 'search_verb'}}"
maxlength="100" autocomplete="off">
</form>
{{/notEq}}

+ 10
- 11
server/sonar-web/src/main/js/apps/update-center/templates/update-center-system-update.hbs View File

@@ -13,45 +13,44 @@
<td class="text-top width-20 big-spacer-right">
<div>
<strong class="js-plugin-name">SonarQube {{version}}</strong>
<span class="js-plugin-category badge badge-success spacer-left">System Upgrade</span>
<span class="js-plugin-category badge badge-success spacer-left">{{t 'update_center.system_upgrade'}}</span>
</div>
<div class="js-plugin-description little-spacer-top">{{{description}}}</div>

<ul class="big-spacer-top">
{{#if changeLogUrl}}
<li class="little-spacer-bottom">
<a class="js-plugin-release-notes" href="{{changeLogUrl}}" target="_blank">Release Notes</a>
<a class="js-plugin-release-notes" href="{{changeLogUrl}}" target="_blank">{{t 'update_center.release_notes'}}</a>
</li>
{{/if}}
{{#if releaseDate}}
<li class="little-spacer-bottom">Released: <span class="js-plugin-date">{{d releaseDate}}</span></li>
<li class="little-spacer-bottom">{{t 'update_center.released'}}: <span class="js-plugin-date">{{d releaseDate}}</span></li>
{{/if}}
</ul>
</td>

<td class="text-top width-60">
<div class="pull-left spacer-right">
<strong>How to upgrade</strong>
<strong>{{t 'update_center.how_to_upgrade'}}</strong>
</div>
<ol class="js-plugin-update-steps list-styled overflow-hidden bordered-left">
<li class="little-spacer-bottom">
Download the new SonarQube version and start it on an empty DB (the bundled H2 DB for instance).
{{t 'update_center.how_to_upgrade.1'}}
</li>
<li class="little-spacer-bottom">
Install (from the update center) the plugins you want.
{{t 'update_center.how_to_upgrade.2'}}
</li>
<li class="little-spacer-bottom">
Install your custom plugins (if any).
{{t 'update_center.how_to_upgrade.3'}}
</li>
<li class="little-spacer-bottom">
Update the <code>conf/sonar.properties</code> file to use the relevant configurations from your old instance,
including the connection information for your production DB.
{{t 'update_center.how_to_upgrade.4'}}
</li>
<li class="little-spacer-bottom">
Stop your old SonarQube server.
{{t 'update_center.how_to_upgrade.5'}}
</li>
<li>
Restart the new SonarQube instance: you're done!
{{t 'update_center.how_to_upgrade.6'}}
</li>
</ol>
</td>

+ 6
- 6
server/sonar-web/src/main/js/apps/users/templates/users-change-password.hbs View File

@@ -1,32 +1,32 @@
<form id="change-user-password-form" autocomplete="off">
<div class="modal-head">
<h2>Change Password</h2>
<h2>{{t 'my_profile.password.title'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
{{#if isOwnPassword}}
<div class="modal-field">
<label for="change-user-password-old-password">Old Password<em class="mandatory">*</em></label>
<label for="change-user-password-old-password">{{t 'my_profile.password.old'}}<em class="mandatory">*</em></label>
{{! keep this fake field to hack browser autofill }}
<input id="change-user-password-old-password-fake" name="old-password-fake" type="password" class="hidden">
<input id="change-user-password-old-password" name="old-password" type="password" size="50" maxlength="50" required>
</div>
{{/if}}
<div class="modal-field">
<label for="change-user-password-password">New Password<em class="mandatory">*</em></label>
<label for="change-user-password-password">{{t 'my_profile.password.new'}}<em class="mandatory">*</em></label>
{{! keep this fake field to hack browser autofill }}
<input id="change-user-password-password-fake" name="password-fake" type="password" class="hidden">
<input id="change-user-password-password" name="password" type="password" size="50" maxlength="50" required>
</div>
<div class="modal-field">
<label for="change-user-password-password-confirmation">Confirm Password<em class="mandatory">*</em></label>
<label for="change-user-password-password-confirmation">{{t 'my_profile.password.confirm'}}<em class="mandatory">*</em></label>
{{! keep this fake field to hack browser autofill }}
<input id="change-user-password-password-confirmation-fake" name="password-confirmation-fake" type="password" class="hidden">
<input id="change-user-password-password-confirmation" name="password-confirmation" type="password" size="50" maxlength="50" required>
</div>
</div>
<div class="modal-foot">
<button id="change-user-password-submit">Change</button>
<a href="#" class="js-modal-close" id="change-user-password-cancel">Cancel</a>
<button id="change-user-password-submit">{{t 'change_verb'}}</button>
<a href="#" class="js-modal-close" id="change-user-password-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 4
- 4
server/sonar-web/src/main/js/apps/users/templates/users-deactivate.hbs View File

@@ -1,13 +1,13 @@
<form id="deactivate-user-form" autocomplete="off">
<div class="modal-head">
<h2>Deactivate User</h2>
<h2>{{t 'users.deactivate_user'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
Are you sure you want to deactivate "{{name}} ({{login}})"?
{{tp 'users.deactivate_user.confirmation' name login}}
</div>
<div class="modal-foot">
<button id="deactivate-user-submit">Deactivate</button>
<a href="#" class="js-modal-close" id="deactivate-user-cancel">Cancel</a>
<button id="deactivate-user-submit">{{t 'users.deactivate'}}</button>
<a href="#" class="js-modal-close" id="deactivate-user-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 10
- 10
server/sonar-web/src/main/js/apps/users/templates/users-form.hbs View File

@@ -1,41 +1,41 @@
<form id="create-user-form" autocomplete="off">
<div class="modal-head">
<h2>{{#if login}}Update{{else}}Create{{/if}} User</h2>
<h2>{{#if login}}{{t 'users.update_user'}}{{else}}{{t 'users.create_user'}}{{/if}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
{{#unless login}}
<div class="modal-field">
<label for="create-user-login">Login<em class="mandatory">*</em></label>
<label for="create-user-login">{{t 'login'}}<em class="mandatory">*</em></label>
{{! keep this fake field to hack browser autofill }}
<input id="create-user-login-fake" name="login-fake" type="text" class="hidden">
<input id="create-user-login" name="login" type="text" size="50" minlength="3" maxlength="255" required
value="{{login}}">
<p class="note">Minimum 3 characters</p>
<p class="note">{{tp 'users.minimum_x_characters' 3}}</p>
</div>
{{/unless}}
<div class="modal-field">
<label for="create-user-name">Name<em class="mandatory">*</em></label>
<label for="create-user-name">{{t 'name'}}<em class="mandatory">*</em></label>
{{! keep this fake field to hack browser autofill }}
<input id="create-user-name-fake" name="name-fake" type="text" class="hidden">
<input id="create-user-name" name="name" type="text" size="50" maxlength="200" required value="{{name}}">
</div>
<div class="modal-field">
<label for="create-user-email">Email</label>
<label for="create-user-email">{{t 'users.email'}}</label>
{{! keep this fake field to hack browser autofill }}
<input id="create-user-email-fake" name="email-fake" type="email" class="hidden">
<input id="create-user-email" name="email" type="email" size="50" maxlength="100" value="{{email}}">
</div>
{{#unless login}}
<div class="modal-field">
<label for="create-user-password">Password<em class="mandatory">*</em></label>
<label for="create-user-password">{{t 'password'}}<em class="mandatory">*</em></label>
{{! keep this fake field to hack browser autofill }}
<input id="create-user-password-fake" name="password-fake" type="password" class="hidden">
<input id="create-user-password" name="password" type="password" size="50" maxlength="50" required>
</div>
{{/unless}}
<div class="modal-field">
<label>SCM Accounts</label>
<label>{{t 'my_profile.scm_accounts'}}</label>
{{#each scmAccounts}}
<input name="scmAccounts" type="text" size="50" maxlength="255" value="{{this}}">
{{else}}
@@ -43,11 +43,11 @@
{{/each}}
<a id="create-user-add-scm-account" class="icon-plus" href="#" title="Add another SCM account"
data-toggle="tooltip"></a>
<p class="note">Note that login and email are automatically considered as SCM accounts</p>
<p class="note">{{t 'user.login_or_email_used_as_scm_account'}}</p>
</div>
</div>
<div class="modal-foot">
<button id="create-user-submit">{{#if login}}Update{{else}}Create{{/if}}</button>
<a href="#" class="js-modal-close" id="create-user-cancel">Cancel</a>
<button id="create-user-submit">{{#if login}}{{t 'update_verb'}}{{else}}{{t 'create'}}{{/if}}</button>
<a href="#" class="js-modal-close" id="create-user-cancel">{{t 'cancel'}}</a>
</div>
</form>

+ 2
- 2
server/sonar-web/src/main/js/apps/users/templates/users-groups.hbs View File

@@ -1,10 +1,10 @@
<div class="modal-head">
<h2>Update Groups</h2>
<h2>{{t 'users.update_groups'}}</h2>
</div>
<div class="modal-body">
<div class="js-modal-messages"></div>
<div id="users-groups"></div>
</div>
<div class="modal-foot">
<a href="#" class="js-modal-close" id="users-groups-done">Done</a>
<a href="#" class="js-modal-close" id="users-groups-done">{{t 'Done'}}</a>
</div>

+ 1
- 1
server/sonar-web/src/main/js/apps/users/templates/users-header.hbs View File

@@ -3,7 +3,7 @@
<i class="spinner hidden"></i>
<div class="page-actions">
<div class="button-group">
<button id="users-create">Create User</button>
<button id="users-create">{{t 'users.create_user'}}</button>
</div>
</div>
<p class="page-description">{{t 'users.page.description'}}</p>

+ 2
- 2
server/sonar-web/src/main/js/apps/users/templates/users-list-footer.hbs View File

@@ -1,6 +1,6 @@
<footer class="spacer-top note text-center">
{{count}}/{{total}} shown
{{tp 'x_of_y_shown' count total}}
{{#if more}}
<a id="users-fetch-more" class="spacer-left" href="#">show more</a>
<a id="users-fetch-more" class="spacer-left" href="#">{{t 'show_more'}}</a>
{{/if}}
</footer>

+ 7
- 7
server/sonar-web/src/main/js/apps/users/templates/users-list-item.hbs View File

@@ -35,7 +35,7 @@
{{/each}}
{{#gt moreScmAccountsCount 0}}
<li class="little-spacer-bottom">
<a class="js-user-more-scm" href="#">{{moreScmAccountsCount}} more</a>
<a class="js-user-more-scm" href="#">{{moreScmAccountsCount}} {{t 'more'}}</a>
</li>
{{/gt}}
</ul>
@@ -49,9 +49,9 @@
{{/each}}
<li class="little-spacer-bottom">
{{#gt moreGroupsCount 0}}
<a class="js-user-more-groups spacer-right" href="#">{{moreGroupsCount}} more</a>
<a class="js-user-more-groups spacer-right" href="#">{{moreGroupsCount}} {{t 'more'}}</a>
{{/gt}}
<a class="js-user-groups icon-bullet-list" title="Update Groups" data-toggle="tooltip" href="#"></a>
<a class="js-user-groups icon-bullet-list" title="{{t 'users.update_groups'}}" data-toggle="tooltip" href="#"></a>
</li>
</ul>
</td>
@@ -59,14 +59,14 @@

<td>
{{tokensCount}}
<a class="js-user-tokens spacer-left icon-bullet-list" title="Update Tokens" data-toggle="tooltip" href="#"></a>
<a class="js-user-tokens spacer-left icon-bullet-list" title="{{t 'users.update_tokens'}}" data-toggle="tooltip" href="#"></a>
</td>

<td class="thin nowrap text-right">
<a class="js-user-update icon-edit little-spacer-right" title="Update Details" data-toggle="tooltip" href="#"></a>
<a class="js-user-update icon-edit little-spacer-right" title="{{t 'update_details'}}" data-toggle="tooltip" href="#"></a>
{{#if local}}
<a class="js-user-change-password icon-lock little-spacer-right" title="Change Password" data-toggle="tooltip"
<a class="js-user-change-password icon-lock little-spacer-right" title="{{t 'my_profile.password.title'}}" data-toggle="tooltip"
href="#"></a>
{{/if}}
<a class="js-user-deactivate icon-delete" title="Deactivate" data-toggle="tooltip" href="#"></a>
<a class="js-user-deactivate icon-delete" title="{{t 'users.deactivate'}}" data-toggle="tooltip" href="#"></a>
</td>

+ 3
- 3
server/sonar-web/src/main/js/apps/users/templates/users-list.hbs View File

@@ -3,11 +3,11 @@
<tr>
<th>&nbsp;</th>
<th class="nowrap">&nbsp;</th>
<th class="nowrap">SCM Accounts</th>
<th class="nowrap">{{t 'my_profile.scm_accounts'}}</th>
{{#unless customOrganizations}}
<th class="nowrap">Groups</th>
<th class="nowrap">{{t 'my_profile.groups'}}</th>
{{/unless}}
<th class="nowrap">Tokens</th>
<th class="nowrap">{{t 'users.tokens'}}</th>
<th class="nowrap">&nbsp;</th>
</tr>
</thead>

+ 1
- 1
server/sonar-web/src/main/js/apps/users/templates/users-search.hbs View File

@@ -1,7 +1,7 @@
<div class="panel panel-vertical bordered-bottom spacer-bottom">
<form id="users-search-form" class="search-box">
<button id="users-search-submit" class="search-box-submit button-clean"><i class="icon-search"></i></button>
<input id="users-search-query" class="search-box-input" type="search" name="q" placeholder="Search" maxlength="100">
<input id="users-search-query" class="search-box-input" type="search" name="q" placeholder="{{t 'search_verb'}}" maxlength="100">
<span class="js-hint note spacer-left text-middle hidden">
{{tp 'select2.tooShort' 2}}
</span>

+ 12
- 12
server/sonar-web/src/main/js/apps/users/templates/users-tokens.hbs View File

@@ -1,5 +1,5 @@
<div class="modal-head">
<h2>Tokens</h2>
<h2>{{t 'users.tokens'}}</h2>
</div>

<div class="modal-body">
@@ -9,8 +9,8 @@
<table class="data zebra">
<thead>
<tr>
<th>Name</th>
<th class="text-right">Created</th>
<th>{{t 'name'}}</th>
<th class="text-right">{{t 'created'}}</th>
<th>&nbsp;</th>
</tr>
</thead>
@@ -29,9 +29,9 @@
<div class="big-spacer-left">
<form class="js-revoke-token-form" data-token="{{name}}">
{{#if deleting}}
<button class="button-red active input-small">Sure?</button>
<button class="button-red active input-small">{{t 'users.tokens.sure'}}</button>
{{else}}
<button class="button-red input-small">Revoke</button>
<button class="button-red input-small">{{t 'users.tokens.revoke'}}</button>
{{/if}}
</form>
</div>
@@ -40,7 +40,7 @@
{{else}}
<tr>
<td colspan="3">
<span class="note">No tokens</span>
<span class="note">{{t 'users.no_tokens'}}</span>
</td>
</tr>
{{/each}}
@@ -50,28 +50,28 @@

<hr class="big-spacer-top big-spacer-bottom">

<h3 class="spacer-bottom">Generate Tokens</h3>
<h3 class="spacer-bottom">{{t 'users.generate_tokens'}}</h3>

{{#each errors}}
<div class="alert alert-danger">{{msg}}</div>
{{/each}}

<form class="js-generate-token-form">
<input type="text" required maxlength="100" placeholder="Enter Token Name">
<button>Generate</button>
<input type="text" required maxlength="100" placeholder="{{t 'users.enter_token_name'}}">
<button>{{t 'users.generate'}}</button>
</form>

{{#if newToken}}
<div class="panel panel-white big-spacer-top">
<div class="alert alert-warning">
New token "{{limitString newToken.name}}" has been created. Make sure you copy it now, you won’t be able to see it again!
{{tp 'users.tokens.new_token_created' newToken.name}}
</div>

<table class="data">
<tr>

<td class="thin">
<button class="js-copy-to-clipboard" data-clipboard-text="{{newToken.token}}">Copy</button>
<button class="js-copy-to-clipboard" data-clipboard-text="{{newToken.token}}">{{t 'copy'}}</button>
</td>
<td class="nowrap">
<code class="text-success">{{newToken.token}}</code>
@@ -83,5 +83,5 @@
</div>

<div class="modal-foot">
<a href="#" class="js-modal-close">Done</a>
<a href="#" class="js-modal-close">{{t 'Done'}}</a>
</div>

+ 6
- 1
server/sonar-web/src/main/js/apps/users/tokens-view.js View File

@@ -22,6 +22,7 @@ import Clipboard from 'clipboard';
import Modal from '../../components/common/modals';
import Template from './templates/users-tokens.hbs';
import { getTokens, generateToken, revokeToken } from '../../api/user-tokens';
import { translate } from '../../helpers/l10n';

export default Modal.extend({
template: Template,
@@ -84,7 +85,11 @@ export default Modal.extend({
const clipboard = new Clipboard(copyButton.get(0));
clipboard.on('success', () => {
copyButton
.tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' })
.tooltip({
title: translate('users.tokens.copied'),
placement: 'bottom',
trigger: 'manual'
})
.tooltip('show');
setTimeout(() => copyButton.tooltip('hide'), 1000);
});

+ 5
- 2
server/sonar-web/src/main/js/components/SourceViewer/views/measures-overlay.js View File

@@ -25,6 +25,7 @@ import ModalView from '../../common/modals';
import Template from './templates/source-viewer-measures.hbs';
import { getMeasures } from '../../../api/measures';
import { getMetrics } from '../../../api/metrics';
import { getLocalizedMetricName, getLocalizedMetricDomain } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';

const severityComparator = severity => {
@@ -134,11 +135,13 @@ export default ModalView.extend({
},

prepareMetrics(metrics) {
metrics = metrics.filter(metric => metric.value != null);
metrics = metrics
.filter(metric => metric.value != null)
.map(metric => ({ ...metric, name: getLocalizedMetricName(metric) }));
return sortBy(
toPairs(groupBy(metrics, 'domain')).map(domain => {
return {
name: domain[0],
name: getLocalizedMetricDomain(domain[0]),
metrics: domain[1]
};
}),

+ 1
- 1
server/sonar-web/src/main/js/components/SourceViewer/views/templates/_source-viewer-measures-duplications.hbs View File

@@ -10,7 +10,7 @@
</div>
<div class="measure measure-big" data-metric="duplicated_lines_density">
<span class="measure-value">{{measures.duplicated_lines_density}}</span>
<span class="measure-name">Duplications</span>
<span class="measure-name">{{t 'metric.duplicated_lines_density.short_name'}}</span>
</div>
</div>


+ 1
- 1
server/sonar-web/src/main/js/components/SourceViewer/views/templates/_source-viewer-measures-lines.hbs View File

@@ -9,7 +9,7 @@
<span class="measure-value">{{measures.ncloc}}</span>
</div>
<div class="measure measure-one-line" data-metric="comment_lines">
<span class="measure-name">Comments</span>
<span class="measure-name">{{t 'metric.comment_lines_density.short_name'}}</span>
<span class="measure-value">{{measures.comment_lines_density}} / {{measures.comment_lines}}</span>
</div>
</div>

+ 168
- 725
sonar-core/src/main/resources/org/sonar/l10n/core.properties
File diff suppressed because it is too large
View File


+ 1
- 1
sonar-core/src/test/java/org/sonar/core/i18n/DefaultI18nTest.java View File

@@ -156,7 +156,7 @@ public class DefaultI18nTest {

@Test
public void format_message_with_parameters() {
assertThat(underTest.message(Locale.ENGLISH, "name_too_long_x", null, "10")).isEqualTo("Name is too long (maximum is 10 characters)");
assertThat(underTest.message(Locale.ENGLISH, "x_results", null, "10")).isEqualTo("10 results");
}

@Test

Loading…
Cancel
Save