@@ -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> | |||
)} |
@@ -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> |
@@ -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> |
@@ -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 { |
@@ -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> | |||
)} | |||
@@ -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> </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> |
@@ -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); | |||
}); |
@@ -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> | |||
); |
@@ -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} |
@@ -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', |
@@ -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}} {{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}} |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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"> |
@@ -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> </th> | |||
</tr> | |||
</thead> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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,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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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}} |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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,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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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"> |
@@ -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> |
@@ -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> | |||
@@ -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> | |||
); |
@@ -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> |
@@ -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> | |||
`; |
@@ -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> |
@@ -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> |
@@ -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> | |||
)} |
@@ -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> |
@@ -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> |
@@ -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 ( |
@@ -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> |
@@ -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="" | |||
/> |
@@ -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)}> |
@@ -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)} |
@@ -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> |
@@ -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> | |||
)} |
@@ -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" |
@@ -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}} |
@@ -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,3 +1,3 @@ | |||
<footer class="spacer-top note text-center"> | |||
{{total}} shown | |||
{{tp 'x_show' total}} | |||
</footer> |
@@ -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,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}} |
@@ -14,12 +14,12 @@ | |||
<ul> | |||
{{#if version}} | |||
<li class="little-spacer-bottom"> | |||
<strong class="js-plugin-installed-version">{{version}}</strong> installed | |||
<strong class="js-plugin-installed-version">{{version}}</strong> {{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'}} |
@@ -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}} |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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,11 +3,11 @@ | |||
<tr> | |||
<th> </th> | |||
<th class="nowrap"> </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"> </th> | |||
</tr> | |||
</thead> |
@@ -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> |
@@ -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> </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> |
@@ -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); | |||
}); |
@@ -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] | |||
}; | |||
}), |
@@ -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> | |||
@@ -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> |
@@ -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 |