diff options
21 files changed, 224 insertions, 109 deletions
diff --git a/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx b/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx index eacbe1883b0..5baa8f12be9 100644 --- a/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx +++ b/server/sonar-web/src/main/js/app/components/GlobalFooter.tsx @@ -22,6 +22,7 @@ import * as PropTypes from 'prop-types'; import { Link } from 'react-router'; import GlobalFooterSonarCloud from './GlobalFooterSonarCloud'; import GlobalFooterBranding from './GlobalFooterBranding'; +import InstanceMessage from '../../components/common/InstanceMessage'; import { translate, translateWithParameters } from '../../helpers/l10n'; interface Props { @@ -48,7 +49,9 @@ export default class GlobalFooter extends React.PureComponent<Props> { <p className="big" id="evaluation_warning"> {translate('footer.production_database_warning')} </p> - <p>{translate('footer.production_database_explanation')}</p> + <p> + <InstanceMessage message={translate('footer.production_database_explanation')} /> + </p> </div> )} diff --git a/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalFooter-test.tsx.snap b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalFooter-test.tsx.snap index b7069f5b1cb..7b42faddf53 100644 --- a/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalFooter-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/__tests__/__snapshots__/GlobalFooter-test.tsx.snap @@ -236,7 +236,9 @@ exports[`should show the db warning message 1`] = ` footer.production_database_warning </p> <p> - footer.production_database_explanation + <InstanceMessage + message="footer.production_database_explanation" + /> </p> </div> `; diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/PendingPluginsActionNotif.tsx b/server/sonar-web/src/main/js/app/components/nav/settings/PendingPluginsActionNotif.tsx index 72658160bfb..5f475b3d27a 100644 --- a/server/sonar-web/src/main/js/app/components/nav/settings/PendingPluginsActionNotif.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/settings/PendingPluginsActionNotif.tsx @@ -19,11 +19,12 @@ */ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; +import InstanceMessage from '../../../../components/common/InstanceMessage'; +import NavBarNotif from '../../../../components/nav/NavBarNotif'; import RestartForm from '../../../../components/common/RestartForm'; import { cancelPendingPlugins, PluginPendingResult } from '../../../../api/plugins'; import { Button } from '../../../../components/ui/buttons'; import { translate } from '../../../../helpers/l10n'; -import NavBarNotif from '../../../../components/nav/NavBarNotif'; interface Props { pending: PluginPendingResult; @@ -59,7 +60,7 @@ export default class PendingPluginsActionNotif extends React.PureComponent<Props return ( <NavBarNotif className="alert alert-info js-pending"> <span className="little-spacer-right"> - {translate('marketplace.sonarqube_needs_to_be_restarted_to')} + <InstanceMessage message={translate('marketplace.instance_needs_to_be_restarted_to')} /> </span> {[ { length: installing.length, msg: 'marketplace.install_x_plugins' }, diff --git a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/PendingPluginsActionNotif-test.tsx.snap b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/PendingPluginsActionNotif-test.tsx.snap index 2a461de7565..404b2a96734 100644 --- a/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/PendingPluginsActionNotif-test.tsx.snap +++ b/server/sonar-web/src/main/js/app/components/nav/settings/__tests__/__snapshots__/PendingPluginsActionNotif-test.tsx.snap @@ -7,7 +7,9 @@ exports[`should display pending actions 1`] = ` <span className="little-spacer-right" > - marketplace.sonarqube_needs_to_be_restarted_to + <InstanceMessage + message="marketplace.instance_needs_to_be_restarted_to" + /> </span> <span key="marketplace.install_x_plugins" diff --git a/server/sonar-web/src/main/js/apps/account/components/Tokens.tsx b/server/sonar-web/src/main/js/apps/account/components/Tokens.tsx index db6a74adf1c..475d98eef83 100644 --- a/server/sonar-web/src/main/js/apps/account/components/Tokens.tsx +++ b/server/sonar-web/src/main/js/apps/account/components/Tokens.tsx @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; +import InstanceMessage from '../../../components/common/InstanceMessage'; import TokenForm from '../../users/components/TokensForm'; import { translate } from '../../../helpers/l10n'; @@ -31,7 +32,7 @@ export default function Tokens({ login }: Props) { <h2>{translate('users.tokens')}</h2> <div className="boxed-group-inner"> <div className="big-spacer-bottom big-spacer-right markdown"> - {translate('my_account.tokens_description')} + <InstanceMessage message={translate('my_account.tokens_description')} /> </div> <TokenForm login={login} /> diff --git a/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Tokens-test.tsx.snap b/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Tokens-test.tsx.snap index f495a2fa244..e7bd83f8209 100644 --- a/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Tokens-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/account/components/__tests__/__snapshots__/Tokens-test.tsx.snap @@ -13,7 +13,9 @@ exports[`renders 1`] = ` <div className="big-spacer-bottom big-spacer-right markdown" > - my_account.tokens_description + <InstanceMessage + message="my_account.tokens_description" + /> </div> <TokensForm login="user" diff --git a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx index bb80abd464f..8b3978ea92b 100644 --- a/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx +++ b/server/sonar-web/src/main/js/apps/coding-rules/components/RuleDetailsProfiles.tsx @@ -25,12 +25,13 @@ import RuleInheritanceIcon from './RuleInheritanceIcon'; import { Profile, deactivateRule, activateRule } from '../../../api/quality-profiles'; import { RuleActivation, RuleDetails, RuleInheritance } from '../../../app/types'; import ConfirmButton from '../../../components/controls/ConfirmButton'; -import { translate, translateWithParameters } from '../../../helpers/l10n'; -import { getQualityProfileUrl } from '../../../helpers/urls'; import BuiltInQualityProfileBadge from '../../quality-profiles/components/BuiltInQualityProfileBadge'; -import Tooltip from '../../../components/controls/Tooltip'; +import InstanceMessage from '../../../components/common/InstanceMessage'; import SeverityHelper from '../../../components/shared/SeverityHelper'; +import Tooltip from '../../../components/controls/Tooltip'; import { Button } from '../../../components/ui/buttons'; +import { getQualityProfileUrl } from '../../../helpers/urls'; +import { translate, translateWithParameters } from '../../../helpers/l10n'; interface Props { activations: RuleActivation[] | undefined; @@ -262,7 +263,7 @@ export default class RuleDetailsProfiles extends React.PureComponent<Props, Stat <div className="coding-rule-section-separator" /> <h3 className="coding-rules-detail-title"> - {translate('coding_rules.quality_profiles')} + <InstanceMessage message={translate('coding_rules.quality_profiles')} /> </h3> {canActivate && ( diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx index e68bb78f79c..bdc610e13d3 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationDelete.tsx @@ -22,6 +22,7 @@ import * as PropTypes from 'prop-types'; import Helmet from 'react-helmet'; import { connect } from 'react-redux'; import ConfirmButton from '../../../components/controls/ConfirmButton'; +import InstanceMessage from '../../../components/common/InstanceMessage'; import { translate } from '../../../helpers/l10n'; import { deleteOrganization } from '../actions'; import { Organization } from '../../../app/types'; @@ -87,7 +88,6 @@ export class OrganizationDelete extends React.PureComponent<Props, State> { render() { const { hasPaidPlan } = this.state; - const { onSonarCloud } = this.context; const title = translate('organization.delete'); return ( <> @@ -96,9 +96,7 @@ export class OrganizationDelete extends React.PureComponent<Props, State> { <header className="page-header"> <h1 className="page-title">{title}</h1> <div className="page-description"> - {onSonarCloud - ? translate('organization.delete.description.sonarcloud') - : translate('organization.delete.description')} + <InstanceMessage message={translate('organization.delete.description')} /> </div> </header> <ConfirmButton diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationDelete-test.tsx.snap b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationDelete-test.tsx.snap index 0f7e0df211a..62ab31e51d2 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationDelete-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationDelete-test.tsx.snap @@ -21,7 +21,9 @@ exports[`should show a info message for paying organization 1`] = ` <div className="page-description" > - organization.delete.description.sonarcloud + <InstanceMessage + message="organization.delete.description" + /> </div> </header> <ConfirmButton @@ -65,7 +67,9 @@ exports[`smoke test 1`] = ` <div className="page-description" > - organization.delete.description + <InstanceMessage + message="organization.delete.description" + /> </div> </header> <ConfirmButton diff --git a/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js b/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js index 4be5290b446..c306578dbb3 100644 --- a/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js +++ b/server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js @@ -21,6 +21,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import HelpTooltip from '../../../components/controls/HelpTooltip'; import { translate } from '../../../helpers/l10n'; +import InstanceMessage from '../../../components/common/InstanceMessage'; export default class ListHeader extends React.PureComponent { static propTypes = { @@ -31,13 +32,13 @@ export default class ListHeader extends React.PureComponent { renderTooltip = permission => permission.key === 'user' || permission.key === 'codeviewer' ? ( <div> - {translate('projects_role', permission.key, 'desc')} + <InstanceMessage message={translate('projects_role', permission.key, 'desc')} /> <div className="alert alert-warning spacer-top"> {translate('projects_role.public_projects_warning')} </div> </div> ) : ( - translate('projects_role', permission.key, 'desc') + <InstanceMessage message={translate('projects_role', permission.key, 'desc')} /> ); render() { diff --git a/server/sonar-web/src/main/js/apps/permissions/shared/components/PermissionHeader.tsx b/server/sonar-web/src/main/js/apps/permissions/shared/components/PermissionHeader.tsx index 07d1787fded..0c3a6f6865a 100644 --- a/server/sonar-web/src/main/js/apps/permissions/shared/components/PermissionHeader.tsx +++ b/server/sonar-web/src/main/js/apps/permissions/shared/components/PermissionHeader.tsx @@ -19,6 +19,7 @@ */ import * as React from 'react'; import HelpTooltip from '../../../../components/controls/HelpTooltip'; +import InstanceMessage from '../../../../components/common/InstanceMessage'; import Tooltip from '../../../../components/controls/Tooltip'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; @@ -46,14 +47,14 @@ export default class PermissionHeader extends React.PureComponent<Props> { if (this.props.showPublicProjectsWarning && ['user', 'codeviewer'].includes(permission.key)) { return ( <div> - {permission.description} + <InstanceMessage message={permission.description} /> <div className="alert alert-warning spacer-top"> {translate('projects_role.public_projects_warning')} </div> </div> ); } - return permission.description; + return <InstanceMessage message={permission.description} />; }; render() { diff --git a/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js b/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js index d1e1ff72682..77e21d06141 100644 --- a/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js +++ b/server/sonar-web/src/main/js/apps/settings/components/PageHeader.js @@ -20,6 +20,7 @@ // @flow import React from 'react'; import PropTypes from 'prop-types'; +import InstanceMessage from '../../../components/common/InstanceMessage'; import { translate } from '../../../helpers/l10n'; export default class PageHeader extends React.PureComponent { @@ -34,9 +35,11 @@ export default class PageHeader extends React.PureComponent { : translate('settings.page'); const description = - this.props.component != null - ? translate('project_settings.page.description') - : translate('settings.page.description'); + this.props.component != null ? ( + translate('project_settings.page.description') + ) : ( + <InstanceMessage message={translate('settings.page.description')} /> + ); return ( <header className="page-header"> diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js index f85eb470a9d..2b7e5f2bca5 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/Onboarding.js @@ -25,10 +25,11 @@ import TokenStep from './TokenStep'; import OrganizationStep from './OrganizationStep'; import AnalysisStep from './AnalysisStep'; import ProjectWatcher from './ProjectWatcher'; +import InstanceMessage from '../../../components/common/InstanceMessage'; +import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication'; import { skipOnboarding } from '../../../api/users'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { getProjectUrl } from '../../../helpers/urls'; -import handleRequiredAuthentication from '../../../app/utils/handleRequiredAuthentication'; import './styles.css'; /*:: @@ -148,15 +149,17 @@ export default class Onboarding extends React.PureComponent { let stepNumber = 1; - const header = translate(sonarCloud ? 'onboarding.header.sonarcloud' : 'onboarding.header'); - return ( <div className="modal-container"> - <Helmet title={header} titleTemplate="%s" /> + <InstanceMessage message={translate('onboarding.header')}> + {transformedMessage => <Helmet title={transformedMessage} titleTemplate="%s" />} + </InstanceMessage> <div className="page page-limited onboarding"> <header className="page-header"> - <h1 className="page-title">{header}</h1> + <h1 className="page-title"> + <InstanceMessage message={translate('onboarding.header')} /> + </h1> <div className="page-actions"> {this.state.skipping ? ( <i className="spinner" /> diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap index 57a706a0d5d..373e5949514 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/Onboarding-test.js.snap @@ -4,11 +4,8 @@ exports[`guides for on-premise 1`] = ` <div className="modal-container" > - <HelmetWrapper - defer={true} - encodeSpecialCharacters={true} - title="onboarding.header" - titleTemplate="%s" + <InstanceMessage + message="onboarding.header" /> <div className="page page-limited onboarding" @@ -19,7 +16,9 @@ exports[`guides for on-premise 1`] = ` <h1 className="page-title" > - onboarding.header + <InstanceMessage + message="onboarding.header" + /> </h1> <div className="page-actions" @@ -71,11 +70,8 @@ exports[`guides for on-premise 2`] = ` <div className="modal-container" > - <HelmetWrapper - defer={true} - encodeSpecialCharacters={true} - title="onboarding.header" - titleTemplate="%s" + <InstanceMessage + message="onboarding.header" /> <div className="page page-limited onboarding" @@ -86,7 +82,9 @@ exports[`guides for on-premise 2`] = ` <h1 className="page-title" > - onboarding.header + <InstanceMessage + message="onboarding.header" + /> </h1> <div className="page-actions" @@ -139,11 +137,8 @@ exports[`guides for sonarcloud 1`] = ` <div className="modal-container" > - <HelmetWrapper - defer={true} - encodeSpecialCharacters={true} - title="onboarding.header.sonarcloud" - titleTemplate="%s" + <InstanceMessage + message="onboarding.header" /> <div className="page page-limited onboarding" @@ -154,7 +149,9 @@ exports[`guides for sonarcloud 1`] = ` <h1 className="page-title" > - onboarding.header.sonarcloud + <InstanceMessage + message="onboarding.header" + /> </h1> <div className="page-actions" @@ -219,11 +216,8 @@ exports[`guides for sonarcloud 2`] = ` <div className="modal-container" > - <HelmetWrapper - defer={true} - encodeSpecialCharacters={true} - title="onboarding.header.sonarcloud" - titleTemplate="%s" + <InstanceMessage + message="onboarding.header" /> <div className="page page-limited onboarding" @@ -234,7 +228,9 @@ exports[`guides for sonarcloud 2`] = ` <h1 className="page-title" > - onboarding.header.sonarcloud + <InstanceMessage + message="onboarding.header" + /> </h1> <div className="page-actions" @@ -300,11 +296,8 @@ exports[`guides for sonarcloud 3`] = ` <div className="modal-container" > - <HelmetWrapper - defer={true} - encodeSpecialCharacters={true} - title="onboarding.header.sonarcloud" - titleTemplate="%s" + <InstanceMessage + message="onboarding.header" /> <div className="page page-limited onboarding" @@ -315,7 +308,9 @@ exports[`guides for sonarcloud 3`] = ` <h1 className="page-title" > - onboarding.header.sonarcloud + <InstanceMessage + message="onboarding.header" + /> </h1> <div className="page-actions" diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js index 41913848279..d3cc1c847da 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaGradle.js @@ -20,6 +20,7 @@ // @flow import React from 'react'; import CodeSnippet from '../../../../components/common/CodeSnippet'; +import InstanceMessage from '../../../../components/common/InstanceMessage'; import { translate } from '../../../../helpers/l10n'; /*:: @@ -43,10 +44,14 @@ export default function JavaGradle(props /*: Props */) { return ( <div> <h4 className="spacer-bottom">{translate('onboarding.analysis.java.gradle.header')}</h4> - <p - className="spacer-bottom markdown" - dangerouslySetInnerHTML={{ __html: translate('onboarding.analysis.java.gradle.text.1') }} - /> + <InstanceMessage message={translate('onboarding.analysis.java.gradle.text.1')}> + {transformedMessage => ( + <p + className="spacer-bottom markdown" + dangerouslySetInnerHTML={{ __html: transformedMessage }} + /> + )} + </InstanceMessage> <CodeSnippet snippet={config} /> <p className="spacer-top spacer-bottom markdown"> {translate('onboarding.analysis.java.gradle.text.2')} diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js index a54a97e1443..8a02fb75630 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/JavaMaven.js @@ -20,6 +20,7 @@ // @flow import React from 'react'; import CodeSnippet from '../../../../components/common/CodeSnippet'; +import InstanceMessage from '../../../../components/common/InstanceMessage'; import { translate } from '../../../../helpers/l10n'; /*:: @@ -41,7 +42,9 @@ export default function JavaMaven(props /*: Props */) { return ( <div> <h4 className="spacer-bottom">{translate('onboarding.analysis.java.maven.header')}</h4> - <p className="spacer-bottom markdown">{translate('onboarding.analysis.java.maven.text')}</p> + <p className="spacer-bottom markdown"> + <InstanceMessage message={translate('onboarding.analysis.java.maven.text')} /> + </p> <CodeSnippet snippet={command} /> <p className="big-spacer-top markdown" diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap index fe46b14fff4..401137a9234 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaGradle-test.js.snap @@ -7,13 +7,8 @@ exports[`renders correctly 1`] = ` > onboarding.analysis.java.gradle.header </h4> - <p - className="spacer-bottom markdown" - dangerouslySetInnerHTML={ - Object { - "__html": "onboarding.analysis.java.gradle.text.1", - } - } + <InstanceMessage + message="onboarding.analysis.java.gradle.text.1" /> <CodeSnippet snippet="plugins { @@ -61,13 +56,8 @@ exports[`renders correctly 2`] = ` > onboarding.analysis.java.gradle.header </h4> - <p - className="spacer-bottom markdown" - dangerouslySetInnerHTML={ - Object { - "__html": "onboarding.analysis.java.gradle.text.1", - } - } + <InstanceMessage + message="onboarding.analysis.java.gradle.text.1" /> <CodeSnippet snippet="plugins { diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap index 00a5d783eb5..d4462b957c6 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/commands/__tests__/__snapshots__/JavaMaven-test.js.snap @@ -10,7 +10,9 @@ exports[`renders correctly 1`] = ` <p className="spacer-bottom markdown" > - onboarding.analysis.java.maven.text + <InstanceMessage + message="onboarding.analysis.java.maven.text" + /> </p> <CodeSnippet snippet={ @@ -51,7 +53,9 @@ exports[`renders correctly 2`] = ` <p className="spacer-bottom markdown" > - onboarding.analysis.java.maven.text + <InstanceMessage + message="onboarding.analysis.java.maven.text" + /> </p> <CodeSnippet snippet={ diff --git a/server/sonar-web/src/main/js/components/common/InstanceMessage.tsx b/server/sonar-web/src/main/js/components/common/InstanceMessage.tsx new file mode 100644 index 00000000000..9c68882039d --- /dev/null +++ b/server/sonar-web/src/main/js/components/common/InstanceMessage.tsx @@ -0,0 +1,48 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import * as PropTypes from 'prop-types'; + +interface Props { + children?: (transformedMessage: string) => React.ReactNode; + message: string; +} + +const InstanceMessage: React.SFC<Props> = ( + { children, message }: Props, + context: { onSonarCloud: boolean } +) => { + const transformedMessage = message.replace( + /\{instance\}/gim, + context.onSonarCloud ? 'SonarCloud' : 'SonarQube' + ); + + if (children) { + return children(transformedMessage); + } + + return transformedMessage as any; +}; + +InstanceMessage.contextTypes = { + onSonarCloud: PropTypes.bool +}; + +export default InstanceMessage; diff --git a/server/sonar-web/src/main/js/components/common/__tests__/InstanceMessage-test.tsx b/server/sonar-web/src/main/js/components/common/__tests__/InstanceMessage-test.tsx new file mode 100644 index 00000000000..482d988b92e --- /dev/null +++ b/server/sonar-web/src/main/js/components/common/__tests__/InstanceMessage-test.tsx @@ -0,0 +1,50 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import InstanceMessage from '../InstanceMessage'; + +it('should replace {instance} with "SonarQube"', () => { + const childFunc = jest.fn(); + getWrapper(childFunc, 'foo {instance} bar'); + expect(childFunc).toHaveBeenCalledWith('foo SonarQube bar'); +}); + +it('should replace {instance} with "SonarCloud"', () => { + const childFunc = jest.fn(); + getWrapper(childFunc, 'foo {instance} bar', true); + expect(childFunc).toHaveBeenCalledWith('foo SonarCloud bar'); +}); + +it('should return the same message', () => { + const childFunc = jest.fn(); + getWrapper(childFunc, 'no instance to replace'); + expect(childFunc).toHaveBeenCalledWith('no instance to replace'); +}); + +function getWrapper( + children: (msg: string) => React.ReactNode, + message: string, + onSonarCloud = false +) { + return shallow(<InstanceMessage message={message}>{children}</InstanceMessage>, { + context: { onSonarCloud } + }); +} diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 9d48f94d81c..824627768bf 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -483,7 +483,7 @@ project_links.page=Links project_links.page.description=Edit some links associated with this project. projects_management.page.description=Use this page to delete multiple projects at once, or to provision projects if you would like to configure them before the first analysis. Note that once a project is provisioned, you have access to perform all project configurations on it. settings.page=General Settings -settings.page.description=Edit global settings for this SonarQube instance. +settings.page.description=Edit global settings for this {instance} instance. system_info.page=System Info project_quality_profiles.page=Quality Profiles project_quality_profiles.page.description=Choose which profile is associated with this project on a language-by-language basis. (Note that you will only need to select profiles for multiple languages for multi-language projects.) @@ -1249,7 +1249,7 @@ coding_rules.parameter.empty=(empty) coding_rules.parameters=Parameters coding_rules.parameters.default_value=Default Value: coding_rules.quality_profiles=Quality Profiles -coding_rules.quality_profiles.template_caption=This rule template was activated on the following profiles in previous versions of SonarQube. It is not possible anymore to do so. Instead, please create a custom rule. +coding_rules.quality_profiles.template_caption=This rule template was activated on the following profiles in previous versions of {instance}. It is not possible anymore to do so. Instead, please create a custom rule. coding_rules.quality_profile=Quality Profile coding_rules.reactivate=Reactivate coding_rules.reactivate.help=A rule with the same key has been previously deleted. Please reactivate the existing rule or modify the key to create a new rule. @@ -1425,7 +1425,7 @@ my_account.notifications=Notifications my_account.no_project_notifications=You have not set project notifications yet. my_account.profile=Profile my_account.security=Security -my_account.tokens_description=If you want to enforce security by not providing credentials of a real SonarQube user to run your code scan or to invoke web services, you can provide a User Token as a replacement of the user login. This will increase the security of your installation by not letting your analysis user's password going through your network. +my_account.tokens_description=If you want to enforce security by not providing credentials of a real {instance} user to run your code scan or to invoke web services, you can provide a User Token as a replacement of the user login. This will increase the security of your installation by not letting your analysis user's password going through your network. my_account.projects=Projects my_account.projects.description=Those projects are the ones you are administering. my_account.projects.no_results=You are not administering any project yet. @@ -1948,7 +1948,7 @@ global_permissions.profileadmin.desc=Ability to perform any action on quality pr global_permissions.gateadmin=Administer Quality Gates global_permissions.gateadmin.desc=Ability to perform any action on quality gates. global_permissions.scan=Execute Analysis -global_permissions.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the SonarQube server. +global_permissions.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the {instance} server. global_permissions.provisioning=Create Projects global_permissions.provisioning.desc=Ability to initialize a project so its settings can be configured before the first analysis. global_permissions.filter_by_x_permission=Filter by "{0}" permission @@ -1970,7 +1970,7 @@ organizations_permissions.profileadmin.desc=Ability to perform any action on qua organizations_permissions.gateadmin=Administer Quality Gates organizations_permissions.gateadmin.desc=Ability to perform any action on quality gates. organizations_permissions.scan=Execute Analysis -organizations_permissions.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the SonarQube server. +organizations_permissions.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the {instance} server. organizations_permissions.provisioning=Create Projects organizations_permissions.provisioning.desc=Ability to initialize a project so its settings can be configured before the first analysis. @@ -1994,7 +1994,7 @@ projects_role.user.desc=Access a project, browse its measures and issues, confir projects_role.codeviewer=See Source Code projects_role.codeviewer.desc=View the project's source code. (Users will also need "Browse" permission) projects_role.scan=Execute Analysis -projects_role.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the SonarQube server. +projects_role.scan.desc=Ability to get all settings required to perform an analysis (including the secured settings like passwords) and to push analysis results to the {instance} server. projects_role.bulk_change=Bulk Change projects_role.apply_template=Apply Permission Template projects_role.apply_template_to_xxx=Apply Permission Template To "{0}" @@ -2124,7 +2124,7 @@ workspace.no_rule=The rule has been removed or never existed. #------------------------------------------------------------------------------ marketplace.page=Marketplace marketplace.page.description=Discover and install new features -marketplace.sonarqube_needs_to_be_restarted_to=SonarQube needs to be restarted in order to +marketplace.instance_needs_to_be_restarted_to={instance} needs to be restarted in order to marketplace.install_x_plugins=install {nb} plugins marketplace.update_x_plugins=update {nb} plugins marketplace.uninstall_x_plugins=uninstall {nb} plugins @@ -2386,7 +2386,7 @@ overview.badges.measure.description.VW=This badge dynamically displays the curre overview.badges.measure.description.APP=This badge dynamically displays the current status of one metric of your application. overview.badges.marketing.alt=Scanned on SonarCloud badge overview.badges.marketing.description=This badge lets you advertise that you're using SonarCloud for code quality. -overview.badges.quality_gate.alt=SonarCloud Quality Gate badge +overview.badges.quality_gate.alt=Quality Gate badge overview.badges.quality_gate.description=This badge dynamically displays the current quality gate status of your project. overview.badges.quality_gate.description.APP=This badge dynamically displays the current quality gate status of your application. overview.badges.quality_gate.description.TRK=This badge dynamically displays the current quality gate status of your project. @@ -2524,8 +2524,7 @@ organization.avatar.description=Url of a small image that represents the organiz organization.avatar.preview=Preview organization.created=Organization "{0}" has been created. organization.delete=Delete Organization -organization.delete.description=Delete this organization from SonarQube. All projects belonging to the organization will be deleted as well. The operation cannot be undone. -organization.delete.description.sonarcloud=Delete this organization from SonarCloud. All projects belonging to the organization will be deleted as well. The operation cannot be undone. +organization.delete.description=Delete this organization from {instance}. All projects belonging to the organization will be deleted as well. The operation cannot be undone. organization.delete.sonarcloud.paid_plan_info=Your current paid plan subscription will stop and you won't be charged anymore. organization.delete.question=Are you sure you want to delete this organization? organization.deleted=Organization has been deleted. @@ -2578,7 +2577,7 @@ footer.help=Help footer.license=LGPL v3 footer.news=News footer.plugins=Plugins -footer.production_database_explanation=The embedded database will not scale, it will not support upgrading to newer versions of SonarQube, and there is no support for migrating your data out of it into a different database engine. +footer.production_database_explanation=The embedded database will not scale, it will not support upgrading to newer versions of {instance}, and there is no support for migrating your data out of it into a different database engine. footer.production_database_warning=Embedded database should be used for evaluation purpose only footer.support=Get Support footer.terms=Terms @@ -2592,8 +2591,7 @@ footer.web_api=Web API # ONBOARDING # #------------------------------------------------------------------------------ -onboarding.header=Welcome to SonarQube! -onboarding.header.sonarcloud=Welcome to SonarCloud! +onboarding.header=Welcome to {instance}! onboarding.header.description=Want to quickly analyze a first project? Follow these {0} easy steps. onboarding.token.header=Provide a token @@ -2636,20 +2634,20 @@ onboarding.language.os.win=Windows onboarding.language.os.mac=macOS onboarding.language.project_key=Define a unique project key -onboarding.analysis.java.maven.header=Execute the SonarQube Scanner for Maven from your computer -onboarding.analysis.java.maven.text=Running a SonarQube analysis with Maven is straighforward. You just need to run the following command in your project's folder. -onboarding.analysis.java.maven.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" target="_blank">official documentation of the SonarQube Scanner for Maven</a> for more details. +onboarding.analysis.java.maven.header=Execute the Scanner for Maven from your computer +onboarding.analysis.java.maven.text=Running a {instance} analysis with Maven is straighforward. You just need to run the following command in your project's folder. +onboarding.analysis.java.maven.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-maven.html" target="_blank">official documentation of the Scanner for Maven</a> for more details. -onboarding.analysis.java.gradle.header=Execute the SonarQube Scanner for Gradle from your computer -onboarding.analysis.java.gradle.text.1=Running a SonarQube analysis with Gradle is straighforward. You just need to declare the <code>org.sonarqube</code> plugin in your <code>build.gradle</code> file: +onboarding.analysis.java.gradle.header=Execute the Scanner for Gradle from your computer +onboarding.analysis.java.gradle.text.1=Running an analysis with Gradle is straighforward. You just need to declare the <code>org.sonarqube</code> plugin in your <code>build.gradle</code> file: onboarding.analysis.java.gradle.text.2=and run the following command: -onboarding.analysis.java.gradle.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/gradle.html" target="_blank">official documentation of the SonarQube Scanner for Gradle</a> for more details. +onboarding.analysis.java.gradle.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/gradle.html" target="_blank">official documentation of the Scanner for Gradle</a> for more details. -onboarding.analysis.msbuild.header=Download and unzip the SonarQube Scanner for MSBuild +onboarding.analysis.msbuild.header=Download and unzip the Scanner for MSBuild onboarding.analysis.msbuild.text=And add the executable's directory to the <code>%PATH%</code> environment variable -onboarding.analysis.msbuild.execute=Execute the SonarQube Scanner for MSBuild from your computer -onboarding.analysis.msbuild.execute.text=Running a SonarQube analysis is straighforward. You just need to execute the following commands at the root of your solution. -onboarding.analysis.msbuild.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" target="_blank">official documentation of the SonarQube Scanner for MSBuild</a> for more details. +onboarding.analysis.msbuild.execute=Execute the Scanner for MSBuild from your computer +onboarding.analysis.msbuild.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands at the root of your solution. +onboarding.analysis.msbuild.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner-msbuild.html" target="_blank">official documentation of the Scanner for MSBuild</a> for more details. onboarding.analysis.build_wrapper.header.linux=Download and unzip the Build Wrapper for Linux onboarding.analysis.build_wrapper.header.win=Download and unzip the Build Wrapper for Windows @@ -2658,15 +2656,15 @@ onboarding.analysis.build_wrapper.text.linux=And add the executable's directory onboarding.analysis.build_wrapper.text.win=And add the executable's directory to the <code>%PATH%</code> environment variable onboarding.analysis.build_wrapper.text.mac=And add the executable's directory to the <code>PATH</code> environment variable -onboarding.analysis.sq_scanner.header.linux=Download and unzip the SonarQube Scanner for Linux -onboarding.analysis.sq_scanner.header.win=Download and unzip the SonarQube Scanner for Windows -onboarding.analysis.sq_scanner.header.mac=Download and unzip the SonarQube Scanner for macOS +onboarding.analysis.sq_scanner.header.linux=Download and unzip the Scanner for Linux +onboarding.analysis.sq_scanner.header.win=Download and unzip the Scanner for Windows +onboarding.analysis.sq_scanner.header.mac=Download and unzip the Scanner for macOS onboarding.analysis.sq_scanner.text.linux=And add the <code>bin</code> directory to the <code>PATH</code> environment variable onboarding.analysis.sq_scanner.text.win=And add the <code>bin</code> directory to the <code>%PATH%</code> environment variable onboarding.analysis.sq_scanner.text.mac=And add the <code>bin</code> directory to the <code>PATH</code> environment variable -onboarding.analysis.sq_scanner.execute=Execute the SonarQube Scanner from your computer -onboarding.analysis.sq_scanner.execute.text=Running a SonarQube analysis is straighforward. You just need to execute the following commands in your project's folder. -onboarding.analysis.sq_scanner.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" target="_blank">official documentation of the SonarQube Scanner</a> for more details. +onboarding.analysis.sq_scanner.execute=Execute the Scanner from your computer +onboarding.analysis.sq_scanner.execute.text=Running a {instance} analysis is straighforward. You just need to execute the following commands in your project's folder. +onboarding.analysis.sq_scanner.docs=Please visit the <a href="http://redirect.sonarsource.com/doc/install-configure-scanner.html" target="_blank">official documentation of the Scanner</a> for more details. onboarding.project_watcher.not_started=Once your project is analyzed, this page will refresh automatically. onboarding.project_watcher.in_progress=Analysis is in progress, please wait... |