From a1ae97a0d15fbe5038f219734a9518d13cfde17a Mon Sep 17 00:00:00 2001 From: laurawacrenier Date: Tue, 12 Jun 2018 10:33:12 +0200 Subject: [PATCH] MMF-1319 Document SC specific features (#318) * Adding pages to SonarCloud doc * Add page for paid plan * Adding documentation about integrations in SonarCloud * Add page suggestions * Add inline documentation * Allow to reference SonarCloud links in the documentation * Update the way to install the Bitbucket Cloud App since it is now available in the marketplace --- .../sonar-docs/src/EmbedDocsSuggestions.json | 39 +++++- .../sonar-docs/src/pages/analyze-a-project.md | 25 ++++ .../src/pages/integrations/bitbucketcloud.md | 79 ++++++++++++ .../src/pages/integrations/github.md | 31 +++++ .../src/pages/integrations/index.md | 10 ++ .../sonar-docs/src/pages/integrations/vsts.md | 37 ++++++ .../src/pages/sonarcloud-pricing.md | 72 +++++++++++ .../tooltips/organizations/organization.md | 5 + .../organizations/CreateOrganizationForm.tsx | 6 +- .../components/OrganizationPage.js | 18 +-- .../OrganizationPage-test.js.snap | 3 + .../tutorials/onboarding/OrganizationStep.js | 8 +- .../main/js/apps/tutorials/onboarding/Step.js | 2 +- .../OrganizationStep-test.js.snap | 113 +++++++++++++++++- .../src/main/js/components/docs/DocLink.tsx | 20 ++-- .../js/components/docs/DocMarkdownBlock.tsx | 6 +- .../main/js/components/docs/DocTooltip.tsx | 2 +- .../js/components/docs/DocTooltipLink.tsx | 44 +++++++ .../docs/__tests__/DocLink-test.tsx | 8 ++ .../docs/__tests__/DocTooltipLink-test.tsx | 30 +++++ .../__snapshots__/DocLink-test.tsx.snap | 25 +++- .../__snapshots__/DocTooltip-test.tsx.snap | 1 + .../DocTooltipLink-test.tsx.snap | 35 ++++++ 23 files changed, 586 insertions(+), 33 deletions(-) create mode 100644 server/sonar-docs/src/pages/analyze-a-project.md create mode 100644 server/sonar-docs/src/pages/integrations/bitbucketcloud.md create mode 100644 server/sonar-docs/src/pages/integrations/github.md create mode 100644 server/sonar-docs/src/pages/integrations/index.md create mode 100644 server/sonar-docs/src/pages/integrations/vsts.md create mode 100644 server/sonar-docs/src/pages/sonarcloud-pricing.md create mode 100644 server/sonar-docs/src/tooltips/organizations/organization.md create mode 100644 server/sonar-web/src/main/js/components/docs/DocTooltipLink.tsx create mode 100644 server/sonar-web/src/main/js/components/docs/__tests__/DocTooltipLink-test.tsx create mode 100644 server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltipLink-test.tsx.snap diff --git a/server/sonar-docs/src/EmbedDocsSuggestions.json b/server/sonar-docs/src/EmbedDocsSuggestions.json index fce00fdf549..8408b1cde58 100644 --- a/server/sonar-docs/src/EmbedDocsSuggestions.json +++ b/server/sonar-docs/src/EmbedDocsSuggestions.json @@ -25,7 +25,13 @@ ], "custom_measures": [], "custom_metrics": [], - "global_permissions": [], + "global_permissions": [ + { + "link": "/documentation/organizations/manage-team", + "text": "Manage a Team", + "scope": "sonarcloud" + } + ], "issues": [ { "link": "/documentation/keyboard-shortcuts", @@ -41,6 +47,13 @@ } ], "organization_projects": [ + { + "link": "/documentation/organizations/manage-team", + "text": "Manage a Team", + "scope": "sonarcloud" + } + ], + "organization_space": [ { "link": "/documentation/organizations/index", "text": "Organizations", @@ -58,8 +71,20 @@ "project_activity": [], "project_quality_gate": [], "project_quality_profiles": [], - "projects_management": [], - "projects": [], + "projects_management": [ + { + "link": "/documentation/analyze-a-project", + "text": "Analyze a Project", + "scope": "sonarcloud" + } + ], + "projects": [ + { + "link": "/documentation/analyze-a-project", + "text": "Analyze a Project", + "scope": "sonarcloud" + } + ], "quality_gates": [ { "link": "/documentation/fixing-the-water-leak", @@ -74,7 +99,13 @@ ], "settings": [], "system_info": [], - "user_groups": [], + "user_groups": [ + { + "link": "/documentation/organizations/manage-team", + "text": "Manage a Team", + "scope": "sonarcloud" + } + ], "users": [], "webhooks": [] } diff --git a/server/sonar-docs/src/pages/analyze-a-project.md b/server/sonar-docs/src/pages/analyze-a-project.md new file mode 100644 index 00000000000..d0c4ddc7a58 --- /dev/null +++ b/server/sonar-docs/src/pages/analyze-a-project.md @@ -0,0 +1,25 @@ +--- +title: Analyze a Project +scope: sonarcloud +--- + +## Prepare your organization + +A project must belong to an [organization](/organizations/index). Create one if you intend to collaborate with your team mates, or use your personal organization for test purposes. + +** /!\ Important note for private code:** Newly created organizations and personal organizations are under a free plan by default. This means projects analyzed on these organizations are public by default: the code will be browsable by anyone. If you want private projects, you should [upgrade your organization to a paid plan](/sonarcloud-pricing) in the "Administration > Billing" page of your organization. + +Find the key of your organization, you will need it at later stages. It can be found on the top right corner of your organization's header. + +## Run analysis + +SonarCloud currently does not trigger analyses automatically - this feature will come in a near future. Currently, it's up to you to launch them inside your +existing CI scripts. + +Depending on which cloud solution you are using for your developments, you can rely on dedicated integrations to help you: + +* VSTS: [read our dedicated documentation](/integrations/vsts) +* Bitbucket Cloud: [read our dedicated documentation](/integrations/bitbucketcloud) +* GitHub: [read our dedicated documentation](/integrations/github) + +If you are not using those solutions, you will have to find out what command to execute to run the analysis. Our [tutorial](/#sonarcloud#/onboarding) will help you on this. diff --git a/server/sonar-docs/src/pages/integrations/bitbucketcloud.md b/server/sonar-docs/src/pages/integrations/bitbucketcloud.md new file mode 100644 index 00000000000..4fd2e775166 --- /dev/null +++ b/server/sonar-docs/src/pages/integrations/bitbucketcloud.md @@ -0,0 +1,79 @@ +--- +title: Integration with Bitbucket Cloud +scope: sonarcloud +--- + +## Authentication + +You can connect to SonarCloud using your Bitbucket Cloud account. On the [login page](/#sonarcloud#/sessions/new), just click on the "Log in with Bitbucket" button. + +## Install SonarCloud add-on for Bitbucket Cloud + +Our Bitbucket Cloud application allows users to automate the SonarCloud analysis with Pipelines. It also allows users to view their SonarCloud metrics directly on Bitbucket Cloud via our Code Quality widget and the decoration of pull-requests. + +In Bitbucket Cloud, go to your team's "Settings > Find integrations" page, search for "SonarCloud" in the "Code Quality" category and click on "Add" to install the application. + +## Analyzing with Pipelines + +SonarCloud integrates with Bitbucket Pipelines to make it easier to trigger analyses. Follow the steps: + +1. On SonarCloud, open and follow the "New Project" tutorial available from the `+` icon available at the top right part of the screen. You can copy-paste the command line displayed at the end. + +2. On Bitbucket Cloud, go to the "Settings > Pipelines > Environment variables" page of your team, and add a new SONAR_TOKEN variable that contains the value of the SonarCloud token (something like `9ad01c85336b265406fa6554a9a681a4b281135f`) which you created during the [tutorial](/#sonarcloud#/onboarding) (and which is available inside the command line that you copy-pasted). **Make sure that you click on the "Lock" icon to encrypt and hide this token.** + +3. Inside the `bitbucket-pipelines.yml` file of your repository, copy the command line provided by the tutorial and replace the actual token by its variable name. For example, for a Java Maven-based project, you should have something like: + +``` +script: + -mvn sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=my-team-org -Dsonar.login=$SONAR_TOKEN +``` + +When this change on `bitbucket-pipelines.yml` is committed and pushed, Pipelines should automatically run a new build and therefore trigger the analysis of the repository. Shortly after, your project will appear on SonarCloud in your organization. + +4. Once you see your project in SonarCloud, go to the Bitbucket Cloud "Settings > SonarCloud" page of your repository and find it in the select box to link it. + +From now on, everytime Pipelines triggers a build, SonarCloud will: + +* Analyze every new branch that contains the change on the `bitbucket-pipelines.yml` file. +* Analyze and decorate every pull request based on such a branch. + +## Quality widget + +SonarCloud provides a widget that shows the current quality metrics of your project directly on the repository's Overview page on Bitbucket Cloud. + +If you have configured the analysis with Pipelines as described above, you will see this widget on the "Overview" page of your repository. + +If you haven't configured the analysis with Pipelines (maybe because you are using another CI tool), follow these few steps: + +1. Go to the repository where you want to display the widget. On the "Overview" page, you should see an empty SonarCloud widget. Click on the link inside the empty widget or just go directly to your repository's "Settings > SonarCloud Settings". + +2. If you're not already logged in on SonarCloud, do it by using the options provided there. You can log in with Bitbucket Cloud by clicking on the blue button, or click on "More options" to log in with GitHub or VSTS. + +3. Once you're logged in on SonarCloud, you should see a dropdown allowing you to choose one of the projects you administer. Just choose the one you want to link to this Bitbucket repository and click "Save". + +4. You can now go back to your repository's Overview page on Bitbucket and see the widget with all current SonarCloud metrics displayed. + +If you want to hide this widget (e.g. because your repository is not analyzed on SonarCloud), you can go to the "Settings > SonarCloud" page of your repository and check "Hide repository overview widget". + +## FAQ + +**Do you have a sample project on Bitbucket Cloud?** +For the time being, you can take a look at this very simple JS project: [Sample project analysed on SonarCloud](https://bitbucket.org/bellingard/fab) + +**Pipelines can't find sonar-scanner** +If you want to analyze a non-Java project (JS, TS, PHP, Python, Go, ...), you will need to download and install the [Scanner CLI](https://redirect.sonarsource.com/doc/install-configure-scanner.html) during the execution of your build prior to the actual code scan. You have two options: + +* You can download it (with curl for instance) from the links available on the documentation page and unpack it (preferably in a cached folder for later reuse). +* On Node environments, you can rely on a [community NPM module](https://www.npmjs.com/package/sonarqube-scanner) to install it globally and therefore make it available in the PATH. + +**I don't see the any quality information whereas I configured everything** +Make sure that your browser is not using some extensions like AdBlocks. They tend to break the integration of third-party applications in BitBucket Cloud. + +## Upcoming features and improvements + +There are various areas in which you can expect new features and improvements: + +* Tighter integration with Pipelines (less parameters to pass on the CLI, availability of the scanner, ...) +* Pull request decoration with inline comments to show the issues within the PR +* Better and easier team onboarding +* Automatic analysis (i.e. no need to configure anything from Pipelines) diff --git a/server/sonar-docs/src/pages/integrations/github.md b/server/sonar-docs/src/pages/integrations/github.md new file mode 100644 index 00000000000..ec2977932fd --- /dev/null +++ b/server/sonar-docs/src/pages/integrations/github.md @@ -0,0 +1,31 @@ +--- +title: Integration with GitHub +scope: sonarcloud +--- + +## Authentication + +You can connect to SonarCloud using your GitHub account. On the [login page](/#sonarcloud#/sessions/new), just click on the "Log in with GitHub" button. + +## Trigger analyses + +SonarCloud currently does not trigger analyses automatically. It's up to you to launch them inside your +existing CI scripts. Please follow the [tutorial](/#sonarcloud#/onboarding) to get started. + +If you are using Travis CI, the SonarCloud Travis Add-on will make it easier to activate analyses. Simply follow +the [guide to integrating with Travis CI](https://docs.travis-ci.com/user/sonarcloud/). + +## Activating pull request decoration + +To have your pull requests decorated by SonarCloud in GitHub, you need to [install the SonarCloud application](https://github.com/apps/sonarcloud) on your GitHub organization(s). + +Once installed, there is nothing more to do if you are using the Travis Add-on. In any other case, you will need +to pass the following properties in your script during the analysis: + +``` +sonar.pullrequest.base=master +sonar.pullrequest.branch=feature/my-new-feature +sonar.pullrequest.key=5 +sonar.pullrequest.provider=GitHub +sonar.pullrequest.github.repository=my-company/my-repo +``` diff --git a/server/sonar-docs/src/pages/integrations/index.md b/server/sonar-docs/src/pages/integrations/index.md new file mode 100644 index 00000000000..01fcb49fe8f --- /dev/null +++ b/server/sonar-docs/src/pages/integrations/index.md @@ -0,0 +1,10 @@ +--- +title: Integrations +scope: sonarcloud +--- + +SonarCloud integrates with the following cloud services to help developers get the most out of their code: + +* [Integration with GitHub](/integrations/github) +* [Integration with Bitbucket Cloud](/integrations/bitbucketcloud) +* [Integration with VSTS](/integrations/vsts) diff --git a/server/sonar-docs/src/pages/integrations/vsts.md b/server/sonar-docs/src/pages/integrations/vsts.md new file mode 100644 index 00000000000..4166445e89f --- /dev/null +++ b/server/sonar-docs/src/pages/integrations/vsts.md @@ -0,0 +1,37 @@ +--- +title: Integration with VSTS +scope: sonarcloud +--- + + +## Authentication + +You can connect to SonarCloud using your VSTS account. On the [login page](/#sonarcloud#/sessions/new), just click on the "Log in with VSTS" button. + +** /!\ Warning:** Only work and school VSTS accounts are authorized to login on SonarCloud. + +## Install the SonarCloud VSTS extension + +The SonarCloud VSTS extension brings everything you need to have your projects analyzed on SonarCloud +very quickly: +* Integration with the Build definitions to easily trigger the analysis +* Pull request decoration to get quick feedback on the code changes +* Widget to have the overview quality of your projects inside VSTS dashboards + +Install [SonarCloud extension for VSTS](https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarcloud)by clicking on the "Get it free" button. + +Then follow the comprehensive [Microsoft lab on how to integrate VSTS with SonarCloud](https://aka.ms/sonarcloudlab). + +## Quality Gate Status widget + +You can monitor the Quality Gate status of your projects directly in your VSTS dashboard. Follow these simple steps to configure your widget: + +1. Once the VSTS extension is installed and your project has been successfully analyzed, go to one of your VSTS dashboards (or create one). Click on the pen icon in the bottom right corner of the screen, and then on the "+" icon to add a widget. + +2. In the list of widgets, select the "Code Quality" one and then click on the "Add" button. An empty widget is added to your dashboard. + +3. You can then click on the widget's cogwheel icon to configure it. + + * **For public projects:** you can simply select your project from the dropdown. A searchbar inside the dropdown will help you find it easily. Just select it and click on the "Save" button. + + * **For private projects:** you'll have to log in using the links provided under the dropdown. Once logged in, your private projects will appear in the dropdown. Select the one you are interested in, and click on "Save". \ No newline at end of file diff --git a/server/sonar-docs/src/pages/sonarcloud-pricing.md b/server/sonar-docs/src/pages/sonarcloud-pricing.md new file mode 100644 index 00000000000..c4ce5d2a752 --- /dev/null +++ b/server/sonar-docs/src/pages/sonarcloud-pricing.md @@ -0,0 +1,72 @@ +--- +title: Pricing +scope: sonarcloud +--- + +Subscribing to a paid plan on SonarCloud allows you to analyze unlimited private projects. You can make your code visible by members of your organization only. + +You can activate the paid plan on the "Administration > Billing" page of your organization. + +## How is SonarCloud priced? + +SonarCloud is priced on a monthly basis per lines of code. You pay up front for a maximum number of lines of code to be analyzed in your organization. + +Find your max LOC below to see what it will cost you per month: + +| Up to lines of code | Price per month in € | +| ------------- |--------------:| +| 100k | 10 | +| 250k | 75 | +| 500k | 150 | +| 1M | 250 | +| 2M | 500 | +| 5M | 1'500 | +| 10M | 3'000 | +| 20M | 4'000 | + + +## What's the difference between the free and paid plans? + +2 options are available to start using SonarCloud: free and paid plans. Both plans let you benefit from all the features available on SonarCloud. + +*Free plan:* + +* For open source projects +* Anyone can see your projects +* You choose who can edit your projects +* Unlimited lines of code (LOCs) + +*Paid plan:* + +* If you need (some or all) private projects +* You choose who can see your private projects +* You choose who can edit your projects +* Priced by lines of private code + + +## Can I try a private project on SonarCloud for free? + +Your first 14 days are on us. You just have to upgrade your organization to a paid plan, and fill your credit card information to get started. After your trial, if you love it you can continue using SonarCloud and you will be charged for the plan you selected when you first started your free trial. You can cancel anytime. + +## What is a Line of Code (LOC) on SonarCloud? + +LOCs are computed by summing up the LOCs of each project analyzed in SonarCloud. The LOCs used for a project are the LOCs found during the most recent analysis of this project. + + +## How are Lines of Code (LOCs) counted towards billing? + +Only LOC from your private projects are counted toward your maximum number of LOCs. If you are getting close to the threshold you will be notified to either upgrade your plan or reduce the number of LOCs in your projects. + +## When will I be invoiced? + +You will be invoiced once a month, the day of the month after your trial ends. For example if you start your free trial on January 1st, it will last till January 14th and you will be first billed on January 15th for your upcoming month, aka January 15th to February 15th. + +## Can I stop using the service? + +Yes, you can stop using SonarCloud anytime you want. + +## Still have more questions? + +Contact us [here](https://about.sonarcloud.io/contact). + + diff --git a/server/sonar-docs/src/tooltips/organizations/organization.md b/server/sonar-docs/src/tooltips/organizations/organization.md new file mode 100644 index 00000000000..067008356b2 --- /dev/null +++ b/server/sonar-docs/src/tooltips/organizations/organization.md @@ -0,0 +1,5 @@ +An organization is a space where a team or a whole company can collaborate across many projects. A new organization is on a free plan by default, which means its projects will be public. Subscribe to paid plan to analyze projects privately + +--- + +See also: [Organizations](/organizations/index) and [Pricing](/paid-plan) diff --git a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.tsx b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.tsx index 04254a29e1a..acc43e6de4c 100644 --- a/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.tsx +++ b/server/sonar-web/src/main/js/apps/account/organizations/CreateOrganizationForm.tsx @@ -24,6 +24,7 @@ import * as PropTypes from 'prop-types'; import { createOrganization } from '../../organizations/actions'; import { Organization } from '../../../app/types'; import Modal from '../../../components/controls/Modal'; +import DocTooltip from '../../../components/docs/DocTooltip'; import { translate } from '../../../helpers/l10n'; import { SubmitButton, ResetButtonLink } from '../../../components/ui/buttons'; @@ -126,7 +127,10 @@ class CreateOrganizationForm extends React.PureComponent { return (
-

{translate('my_account.create_organization')}

+

+ {translate('my_account.create_organization')} + +

diff --git a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js index 0b36388f0ab..67077233600 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js +++ b/server/sonar-web/src/main/js/apps/organizations/components/OrganizationPage.js @@ -23,6 +23,7 @@ import Helmet from 'react-helmet'; import { connect } from 'react-redux'; import OrganizationNavigation from '../navigation/OrganizationNavigation'; import NotFound from '../../../app/components/NotFound'; +import Suggestions from '../../../app/components/embed-docs-modal/Suggestions'; import { fetchOrganization } from '../actions'; import { getOrganizationByKey } from '../../../store/rootReducer'; /*:: import type { Organization } from '../../../store/organizations/duck'; */ @@ -69,15 +70,15 @@ export class OrganizationPage extends React.PureComponent { this.mounted = false; } - updateOrganization = (organizationKey /*: string */) => { + stopLoading = () => { if (this.mounted) { - this.setState({ loading: true }); + this.setState({ loading: false }); } - this.props.fetchOrganization(organizationKey).then(() => { - if (this.mounted) { - this.setState({ loading: false }); - } - }); + }; + + updateOrganization = (organizationKey /*: string */) => { + this.setState({ loading: true }); + this.props.fetchOrganization(organizationKey).then(this.stopLoading, this.stopLoading); }; render() { @@ -94,7 +95,8 @@ export class OrganizationPage extends React.PureComponent { return (
- + + {this.props.children}
); diff --git a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationPage-test.js.snap b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationPage-test.js.snap index 46bff666818..260e3f3ffb6 100644 --- a/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationPage-test.js.snap +++ b/server/sonar-web/src/main/js/apps/organizations/components/__tests__/__snapshots__/OrganizationPage-test.js.snap @@ -21,6 +21,9 @@ exports[`smoke test 1`] = ` encodeSpecialCharacters={true} titleTemplate="%s - Foo" /> + + {translate('onboarding.organization.header')} + + + } /> ); } diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Step.js b/server/sonar-web/src/main/js/apps/tutorials/onboarding/Step.js index 572eb59b49b..d9f6394a75f 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/Step.js +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/Step.js @@ -29,7 +29,7 @@ type Props = {| renderForm: () => React.Element<*>, renderResult: () => ?React.Element<*>, stepNumber: number, - stepTitle: string + stepTitle: React.Element<*> | string |}; */ diff --git a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap index 4ff55018414..7e30dedc4a9 100644 --- a/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap +++ b/server/sonar-web/src/main/js/apps/tutorials/onboarding/__tests__/__snapshots__/OrganizationStep-test.js.snap @@ -21,7 +21,15 @@ exports[`works with existing organization 1`] = ` renderForm={[Function]} renderResult={[Function]} stepNumber={1} - stepTitle="onboarding.organization.header" + stepTitle={ + + onboarding.organization.header + + + } >

- onboarding.organization.header + + onboarding.organization.header + + + +

+ } + > +
+ + +
+ } + > + + + + } + > + + + + + + + + + + + + + + + +
+
) { const { children, href, ...other } = props; - if (href && href.startsWith('/')) { + let url = `/documentation/${href.substr(1)}`; + if (href.startsWith(SONARCLOUD_LINK)) { + url = `/${href.substr(SONARCLOUD_LINK.length)}`; + } return ( - + {children} ); } return ( - <> - + + {children} - - + + ); } diff --git a/server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx b/server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx index 4ec569cb432..2d1f1c6579f 100644 --- a/server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx +++ b/server/sonar-web/src/main/js/components/docs/DocMarkdownBlock.tsx @@ -24,6 +24,7 @@ import reactRenderer from 'remark-react'; import DocLink from './DocLink'; import DocParagraph from './DocParagraph'; import DocImg from './DocImg'; +import DocTooltipLink from './DocTooltipLink'; import { separateFrontMatter } from '../../helpers/markdown'; import { isSonarCloud } from '../../helpers/system'; @@ -31,9 +32,10 @@ interface Props { className?: string; content: string | undefined; displayH1?: boolean; + isTooltip?: boolean; } -export default function DocMarkdownBlock({ className, content, displayH1 }: Props) { +export default function DocMarkdownBlock({ className, content, displayH1, isTooltip }: Props) { const parsed = separateFrontMatter(content || ''); return (
@@ -46,7 +48,7 @@ export default function DocMarkdownBlock({ className, content, displayH1 }: Prop // do not render outer
div: React.Fragment, // use custom link to render documentation anchors - a: DocLink, + a: isTooltip ? DocTooltipLink : DocLink, // used to handle `@include` p: DocParagraph, // use custom img tag to render documentation images diff --git a/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx b/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx index c456c9ecd21..754008144a4 100644 --- a/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx +++ b/server/sonar-web/src/main/js/components/docs/DocTooltip.tsx @@ -82,7 +82,7 @@ export default class DocTooltip extends React.PureComponent { {this.state.loading ? ( ) : ( - + )}
); diff --git a/server/sonar-web/src/main/js/components/docs/DocTooltipLink.tsx b/server/sonar-web/src/main/js/components/docs/DocTooltipLink.tsx new file mode 100644 index 00000000000..e539615e600 --- /dev/null +++ b/server/sonar-web/src/main/js/components/docs/DocTooltipLink.tsx @@ -0,0 +1,44 @@ +/* + * 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 { Link } from 'react-router'; +import DetachIcon from '../../components/icons-components/DetachIcon'; + +export default function DocTooltipLink(props: React.AnchorHTMLAttributes) { + const { children, href, ...other } = props; + return ( + + {href && href.startsWith('/') ? ( + + {children} + + ) : ( + + {children} + + )} + + + ); +} diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx b/server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx index ad740c2d833..4b394343c35 100644 --- a/server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx +++ b/server/sonar-web/src/main/js/components/docs/__tests__/DocLink-test.tsx @@ -25,6 +25,14 @@ it('should render simple link', () => { expect(shallow()).toMatchSnapshot(); }); +it('should render documentation link', () => { + expect(shallow()).toMatchSnapshot(); +}); + +it('should render sonarcloud link', () => { + expect(shallow()).toMatchSnapshot(); +}); + it.skip('should render documentation anchor', () => { expect(shallow()).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/DocTooltipLink-test.tsx b/server/sonar-web/src/main/js/components/docs/__tests__/DocTooltipLink-test.tsx new file mode 100644 index 00000000000..21a44671719 --- /dev/null +++ b/server/sonar-web/src/main/js/components/docs/__tests__/DocTooltipLink-test.tsx @@ -0,0 +1,30 @@ +/* + * 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 DocTooltipLink from '../DocTooltipLink'; + +it('should render simple link', () => { + expect(shallow()).toMatchSnapshot(); +}); + +it('should render internal link', () => { + expect(shallow()).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap index d5678b25137..264acc8a5b4 100644 --- a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap @@ -1,16 +1,33 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should render documentation link 1`] = ` + +`; + exports[`should render simple link 1`] = ` - + - + +`; + +exports[`should render sonarcloud link 1`] = ` + `; diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap index cc1d24b0783..f19fea4d065 100644 --- a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap @@ -25,6 +25,7 @@ exports[`should render 2`] = `
} diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltipLink-test.tsx.snap b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltipLink-test.tsx.snap new file mode 100644 index 00000000000..6d718398791 --- /dev/null +++ b/server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltipLink-test.tsx.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render internal link 1`] = ` + + + + +`; + +exports[`should render simple link 1`] = ` + + + + +`; -- 2.39.5