Переглянути джерело

SONAR-10611 use new help tooltips across the app (#203)

tags/7.5
Stas Vilchik 6 роки тому
джерело
коміт
c87c2986e9
75 змінених файлів з 539 додано та 818 видалено
  1. 7
    0
      server/sonar-docs/src/tooltips/branches/no-branch-support.md
  2. 7
    0
      server/sonar-docs/src/tooltips/branches/single-branch.md
  3. 2
    2
      server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java
  4. 12
    6
      server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx
  5. 9
    1
      server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx
  6. 10
    3
      server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/EmbedDocsPopup-test.tsx
  7. 4
    1
      server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap
  8. 13
    29
      server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx
  9. 8
    5
      server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranchesMenu.tsx
  10. 0
    39
      server/sonar-web/src/main/js/app/components/nav/component/SingleBranchHelperPopup.tsx
  11. 2
    2
      server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBranch-test.tsx
  12. 18
    6
      server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap
  13. 16
    14
      server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranchesMenu-test.tsx.snap
  14. 0
    25
      server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/NoBranchSupportPopup-test.tsx.snap
  15. 0
    24
      server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/SingleBranchHelperPopup-test.tsx.snap
  16. 1
    0
      server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx
  17. 0
    6
      server/sonar-web/src/main/js/app/styles/init/icons.css
  18. 2
    0
      server/sonar-web/src/main/js/app/utils/exposeLibraries.ts
  19. 17
    19
      server/sonar-web/src/main/js/apps/background-tasks/components/NoWorkersSupportPopup.tsx
  20. 5
    20
      server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx
  21. 36
    33
      server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap
  22. 3
    8
      server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js
  23. 5
    2
      server/sonar-web/src/main/js/apps/documentation/components/App.tsx
  24. 7
    6
      server/sonar-web/src/main/js/apps/documentation/styles.css
  25. 6
    5
      server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx
  26. 8
    9
      server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js
  27. 8
    11
      server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGate-test.js.snap
  28. 4
    6
      server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js
  29. 3
    4
      server/sonar-web/src/main/js/apps/permissions/shared/components/PermissionHeader.tsx
  30. 1
    1
      server/sonar-web/src/main/js/apps/permissions/styles.css
  31. 8
    5
      server/sonar-web/src/main/js/apps/projectBranches/components/App.tsx
  32. 8
    7
      server/sonar-web/src/main/js/apps/projectBranches/components/__tests__/__snapshots__/App-test.tsx.snap
  33. 3
    8
      server/sonar-web/src/main/js/apps/projects/visualizations/Risk.tsx
  34. 3
    8
      server/sonar-web/src/main/js/apps/projects/visualizations/SimpleBubbleChart.tsx
  35. 8
    9
      server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Risk-test.tsx.snap
  36. 6
    10
      server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/SimpleBubbleChart-test.tsx.snap
  37. 6
    5
      server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx
  38. 10
    16
      server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/Search-test.tsx.snap
  39. 7
    9
      server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx
  40. 1
    7
      server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx
  41. 1
    1
      server/sonar-web/src/main/js/apps/quality-gates/components/List.js
  42. 5
    4
      server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInQualityProfileBadge.tsx
  43. 7
    5
      server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.tsx
  44. 6
    5
      server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx
  45. 7
    6
      server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx
  46. 8
    7
      server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap
  47. 9
    7
      server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap
  48. 10
    10
      server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx
  49. 2
    2
      server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.css
  50. 2
    8
      server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.tsx
  51. 3
    10
      server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/OAuthProviders-test.tsx.snap
  52. 11
    14
      server/sonar-web/src/main/js/apps/web-api/components/Search.tsx
  53. 8
    16
      server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Search-test.tsx.snap
  54. 2
    6
      server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx
  55. 5
    5
      server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap
  56. 6
    7
      server/sonar-web/src/main/js/components/common/BranchStatus.tsx
  57. 4
    10
      server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/BranchStatus-test.tsx.snap
  58. 11
    6
      server/sonar-web/src/main/js/components/controls/HelpTooltip.css
  59. 22
    15
      server/sonar-web/src/main/js/components/controls/HelpTooltip.tsx
  60. 0
    73
      server/sonar-web/src/main/js/components/controls/Popup.tsx
  61. 18
    82
      server/sonar-web/src/main/js/components/controls/Tooltip.css
  62. 32
    5
      server/sonar-web/src/main/js/components/controls/Tooltip.tsx
  63. 2
    0
      server/sonar-web/src/main/js/components/controls/__tests__/Tooltip-test.tsx
  64. 4
    0
      server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Tooltip-test.tsx.snap
  65. 10
    2
      server/sonar-web/src/main/js/components/docs/DocImg.tsx
  66. 2
    1
      server/sonar-web/src/main/js/components/docs/DocInclude.tsx
  67. 10
    3
      server/sonar-web/src/main/js/components/docs/DocLink.tsx
  68. 9
    44
      server/sonar-web/src/main/js/components/docs/DocTooltip.tsx
  69. 0
    9
      server/sonar-web/src/main/js/components/docs/__tests__/DocTooltip-test.tsx
  70. 12
    3
      server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap
  71. 19
    52
      server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap
  72. 4
    11
      server/sonar-web/src/main/js/components/facet/FacetHeader.tsx
  73. 6
    6
      server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetHeader-test.tsx.snap
  74. 5
    5
      server/sonar-web/src/main/js/components/icons-components/HelpIcon.tsx
  75. 3
    7
      sonar-core/src/main/resources/org/sonar/l10n/core.properties

+ 7
- 0
server/sonar-docs/src/tooltips/branches/no-branch-support.md Переглянути файл

@@ -0,0 +1,7 @@
**Get the most out of SonarQube with branches analysis**

Analyze each branch of your project separately with the Developer Edition.

---

[Learn More](https://redirect.sonarsource.com/editions/developer.html)

+ 7
- 0
server/sonar-docs/src/tooltips/branches/single-branch.md Переглянути файл

@@ -0,0 +1,7 @@
**Learn how to analyze branches in SonarQube**

Quickly setup branch analysis and get separate insights for each of your branches and pull requests.

---

[Branches Documentation](/branches/index)

+ 2
- 2
server/sonar-qa-util/src/main/java/org/sonarqube/qa/util/pageobjects/QualityProfilePage.java Переглянути файл

@@ -30,13 +30,13 @@ public class QualityProfilePage {
public QualityProfilePage shouldHaveMissingSonarWayRules(Integer nbRules) {
Selenide.$(".quality-profile-rules-sonarway-missing")
.shouldBe(Condition.visible)
.$("a").shouldHave(Condition.text(nbRules.toString()));
.shouldHave(Condition.text(nbRules.toString()));
return this;
}

public RulesPage showMissingSonarWayRules() {
Selenide.$(".quality-profile-rules-sonarway-missing")
.shouldBe(Condition.visible).$("a").click();
.shouldBe(Condition.visible).$("[data-test=\"rules\"]").click();
return Selenide.page(RulesPage.class);
}


+ 12
- 6
server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopup.tsx Переглянути файл

@@ -21,11 +21,13 @@ import * as React from 'react';
import * as PropTypes from 'prop-types';
import { Link } from 'react-router';
import { SuggestionLink } from './SuggestionsProvider';
import { CurrentUser, isLoggedIn } from '../../types';
import BubblePopup, { BubblePopupPosition } from '../../../components/common/BubblePopup';
import { translate } from '../../../helpers/l10n';
import { getBaseUrl } from '../../../helpers/urls';

interface Props {
currentUser: CurrentUser;
onClose: () => void;
popupPosition?: BubblePopupPosition;
suggestions: Array<SuggestionLink>;
@@ -93,6 +95,7 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
translate('embed_docs.contact_form')
)}
</li>
<li className="divider" />
{this.renderTitle(translate('embed_docs.stay_connected'))}
<li>
{this.renderIconLink('https://about.sonarcloud.io/news/', 'sc-icon.svg', 'Product News')}
@@ -107,11 +110,13 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
renderSonarQubeLinks() {
return (
<React.Fragment>
<li>
<a href="#" onClick={this.onAnalyzeProjectClick}>
{translate('embed_docs.analyze_new_project')}
</a>
</li>
{isLoggedIn(this.props.currentUser) && (
<li>
<a href="#" onClick={this.onAnalyzeProjectClick}>
{translate('embed_docs.analyze_new_project')}
</a>
</li>
)}
<li className="divider" />
{this.renderTitle(translate('embed_docs.get_support'))}
<li>
@@ -128,6 +133,7 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
'Stack Overflow'
)}
</li>
<li className="divider" />
{this.renderTitle(translate('embed_docs.stay_connected'))}
<li>
{this.renderIconLink('https://blog.sonarsource.com/', 'sq-icon.svg', 'Product News')}
@@ -148,7 +154,7 @@ export default class EmbedDocsPopup extends React.PureComponent<Props> {
{this.renderSuggestions()}
<li>
<Link onClick={this.props.onClose} to="/documentation">
{translate('embed_docs.documentation_index')}
{translate('embed_docs.documentation')}
</Link>
</li>
<li>

+ 9
- 1
server/sonar-web/src/main/js/app/components/embed-docs-modal/EmbedDocsPopupHelper.tsx Переглянути файл

@@ -20,12 +20,14 @@
import * as React from 'react';
import EmbedDocsPopup from './EmbedDocsPopup';
import { SuggestionLink } from './SuggestionsProvider';
import { CurrentUser } from '../../types';
import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import HelpIcon from '../../../components/icons-components/HelpIcon';
import Tooltip from '../../../components/controls/Tooltip';
import { translate } from '../../../helpers/l10n';

interface Props {
currentUser: CurrentUser;
showTooltip: boolean;
suggestions: Array<SuggestionLink>;
tooltip: boolean;
@@ -79,7 +81,13 @@ export default class EmbedDocsPopupHelper extends React.PureComponent<Props, Sta
<BubblePopupHelper
isOpen={this.state.helpOpen}
offset={{ horizontal: 12, vertical: -10 }}
popup={<EmbedDocsPopup onClose={this.closeHelp} suggestions={this.props.suggestions} />}
popup={
<EmbedDocsPopup
currentUser={this.props.currentUser}
onClose={this.closeHelp}
suggestions={this.props.suggestions}
/>
}
position="bottomleft"
togglePopup={this.setHelpDisplay}>
<Tooltip

+ 10
- 3
server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/EmbedDocsPopup-test.tsx Переглянути файл

@@ -25,9 +25,16 @@ const suggestions = [{ link: '#', text: 'foo' }, { link: '#', text: 'bar' }];

it('should display suggestion links', () => {
const context = {};
const wrapper = shallow(<EmbedDocsPopups onClose={jest.fn()} suggestions={suggestions} />, {
context
});
const wrapper = shallow(
<EmbedDocsPopups
currentUser={{ isLoggedIn: true }}
onClose={jest.fn()}
suggestions={suggestions}
/>,
{
context
}
);
wrapper.update();
expect(wrapper).toMatchSnapshot();
});

+ 4
- 1
server/sonar-web/src/main/js/app/components/embed-docs-modal/__tests__/__snapshots__/EmbedDocsPopup-test.tsx.snap Переглянути файл

@@ -48,7 +48,7 @@ exports[`should display suggestion links 1`] = `
style={Object {}}
to="/documentation"
>
embed_docs.documentation_index
embed_docs.documentation
</Link>
</li>
<li>
@@ -110,6 +110,9 @@ exports[`should display suggestion links 1`] = `
Stack Overflow
</a>
</li>
<li
className="divider"
/>
<li
className="dropdown-header"
>

+ 13
- 29
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranch.tsx Переглянути файл

@@ -22,8 +22,7 @@ import * as classNames from 'classnames';
import * as PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import ComponentNavBranchesMenu from './ComponentNavBranchesMenu';
import SingleBranchHelperPopup from './SingleBranchHelperPopup';
import NoBranchSupportPopup from './NoBranchSupportPopup';
import DocTooltip from '../../../../components/docs/DocTooltip';
import { BranchLike, Component } from '../../../types';
import * as theme from '../../../theme';
import BranchIcon from '../../../../components/icons-components/BranchIcon';
@@ -35,7 +34,7 @@ import {
} from '../../../../helpers/branches';
import { translate } from '../../../../helpers/l10n';
import PlusCircleIcon from '../../../../components/icons-components/PlusCircleIcon';
import Popup from '../../../../components/controls/Popup';
import HelpTooltip from '../../../../components/controls/HelpTooltip';
import Tooltip from '../../../../components/controls/Tooltip';

interface Props {
@@ -110,10 +109,11 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
if (isShortLivingBranch(currentBranchLike)) {
return currentBranchLike.isOrphan ? (
<span className="note big-spacer-left text-ellipsis flex-shrink">
{translate('branches.orphan_branch')}
<Tooltip overlay={translate('branches.orphan_branches.tooltip')}>
<i className="icon-help spacer-left" />
</Tooltip>
<span className="text-middle">{translate('branches.orphan_branch')}</span>
<HelpTooltip
className="spacer-left"
overlay={translate('branches.orphan_branches.tooltip')}
/>
</span>
) : (
<span className="note big-spacer-left">
@@ -138,26 +138,6 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
}
};

renderSingleBranchPopup = () => (
<Popup overlay={<SingleBranchHelperPopup />}>
{({ onClick }) => (
<a className="display-flex-center spacer-left link-no-underline" href="#" onClick={onClick}>
<PlusCircleIcon fill={theme.blue} size={12} />
</a>
)}
</Popup>
);

renderNoBranchSupportPopup = () => (
<Popup overlay={<NoBranchSupportPopup />}>
{({ onClick }) => (
<a className="display-flex-center spacer-left link-no-underline" href="#" onClick={onClick}>
<PlusCircleIcon fill={theme.gray80} size={12} />
</a>
)}
</Popup>
);

render() {
const { branchLikes, currentBranchLike } = this.props;

@@ -176,7 +156,9 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
fill={theme.gray80}
/>
<span className="note">{displayName}</span>
{this.renderNoBranchSupportPopup()}
<DocTooltip className="spacer-left" doc="branches/no-branch-support">
<PlusCircleIcon fill={theme.gray71} size={12} />
</DocTooltip>
</div>
);
}
@@ -186,7 +168,9 @@ export default class ComponentNavBranch extends React.PureComponent<Props, State
<div className="navbar-context-branches">
<BranchIcon branchLike={currentBranchLike} className="little-spacer-right" />
<span className="note">{displayName}</span>
{this.renderSingleBranchPopup()}
<DocTooltip className="spacer-left" doc="branches/single-branch">
<PlusCircleIcon fill={theme.blue} size={12} />
</DocTooltip>
</div>
);
}

+ 8
- 5
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBranchesMenu.tsx Переглянути файл

@@ -34,7 +34,7 @@ import {
import { translate } from '../../../../helpers/l10n';
import { getBranchLikeUrl } from '../../../../helpers/urls';
import SearchBox from '../../../../components/controls/SearchBox';
import Tooltip from '../../../../components/controls/Tooltip';
import HelpTooltip from '../../../../components/controls/HelpTooltip';

interface Props {
branchLikes: BranchLike[];
@@ -196,10 +196,13 @@ export default class ComponentNavBranchesMenu extends React.PureComponent<Props,
{showDivider && <li className="divider" />}
{showOrphanHeader && (
<li className="dropdown-header">
{translate('branches.orphan_branches')}
<Tooltip overlay={translate('branches.orphan_branches.tooltip')}>
<i className="icon-help spacer-left" />
</Tooltip>
<div className="display-inline-block text-middle">
{translate('branches.orphan_branches')}
</div>
<HelpTooltip
className="spacer-left"
overlay={translate('branches.orphan_branches.tooltip')}
/>
</li>
)}
{showPullRequestHeader && (

+ 0
- 39
server/sonar-web/src/main/js/app/components/nav/component/SingleBranchHelperPopup.tsx Переглянути файл

@@ -1,39 +0,0 @@
/*
* 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 { translate } from '../../../../helpers/l10n';

export default function SingleBranchHelperPopup() {
return (
<>
<h6 className="spacer-bottom">{translate('branches.learn_how_to_analyze')}</h6>
<p className="big-spacer-bottom markdown">
{translate('branches.learn_how_to_analyze.text')}
</p>
<a
className="button"
href="https://redirect.sonarsource.com/doc/branches.html"
rel="noopener noreferrer"
target="_blank">
{translate('about_page.read_documentation')}
</a>
</>
);
}

+ 2
- 2
server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBranch-test.tsx Переглянути файл

@@ -114,7 +114,7 @@ it('renders single branch popup', () => {
/>,
{ context: { branchesEnabled: true } }
);
expect(wrapper.find('Popup')).toMatchSnapshot();
expect(wrapper.find('DocTooltip')).toMatchSnapshot();
});

it('renders no branch support popup', () => {
@@ -127,7 +127,7 @@ it('renders no branch support popup', () => {
/>,
{ context: { branchesEnabled: false } }
);
expect(wrapper.find('Popup')).toMatchSnapshot();
expect(wrapper.find('DocTooltip')).toMatchSnapshot();
});

it('renders nothing on SonarCloud without branch support', () => {

+ 18
- 6
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranch-test.tsx.snap Переглянути файл

@@ -36,9 +36,15 @@ exports[`renders main branch 1`] = `
`;

exports[`renders no branch support popup 1`] = `
<Popup
overlay={<NoBranchSupportPopup />}
/>
<DocTooltip
className="spacer-left"
doc="branches/no-branch-support"
>
<PlusCircleIcon
fill="#b4b4b4"
size={12}
/>
</DocTooltip>
`;

exports[`renders pull request 1`] = `
@@ -150,7 +156,13 @@ exports[`renders short-living branch 1`] = `
`;

exports[`renders single branch popup 1`] = `
<Popup
overlay={<SingleBranchHelperPopup />}
/>
<DocTooltip
className="spacer-left"
doc="branches/single-branch"
>
<PlusCircleIcon
fill="#4b9fd5"
size={12}
/>
</DocTooltip>
`;

+ 16
- 14
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBranchesMenu-test.tsx.snap Переглянути файл

@@ -80,14 +80,15 @@ exports[`renders list 1`] = `
<li
className="dropdown-header"
>
branches.orphan_branches
<Tooltip
overlay="branches.orphan_branches.tooltip"
<div
className="display-inline-block text-middle"
>
<i
className="icon-help spacer-left"
/>
</Tooltip>
branches.orphan_branches
</div>
<HelpTooltip
className="spacer-left"
overlay="branches.orphan_branches.tooltip"
/>
</li>
<ComponentNavBranchesMenuItem
branchLike={
@@ -177,14 +178,15 @@ exports[`renders list 1`] = `
<li
className="dropdown-header"
>
branches.orphan_branches
<Tooltip
overlay="branches.orphan_branches.tooltip"
<div
className="display-inline-block text-middle"
>
<i
className="icon-help spacer-left"
/>
</Tooltip>
branches.orphan_branches
</div>
<HelpTooltip
className="spacer-left"
overlay="branches.orphan_branches.tooltip"
/>
</li>
<ComponentNavBranchesMenuItem
branchLike={

+ 0
- 25
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/NoBranchSupportPopup-test.tsx.snap Переглянути файл

@@ -1,25 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders 1`] = `
<React.Fragment>
<h6
className="spacer-bottom"
>
branches.no_support.header
</h6>
<p
className="big-spacer-bottom markdown"
>
branches.no_support.header.text
</p>
<p>
<a
href="https://redirect.sonarsource.com/editions/developer.html"
rel="noopener noreferrer"
target="_blank"
>
learn_more
</a>
</p>
</React.Fragment>
`;

+ 0
- 24
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/SingleBranchHelperPopup-test.tsx.snap Переглянути файл

@@ -1,24 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders 1`] = `
<React.Fragment>
<h6
className="spacer-bottom"
>
branches.learn_how_to_analyze
</h6>
<p
className="big-spacer-bottom markdown"
>
branches.learn_how_to_analyze.text
</p>
<a
className="button"
href="https://redirect.sonarsource.com/doc/branches.html"
rel="noopener noreferrer"
target="_blank"
>
about_page.read_documentation
</a>
</React.Fragment>
`;

+ 1
- 0
server/sonar-web/src/main/js/app/components/nav/global/GlobalNav.tsx Переглянути файл

@@ -101,6 +101,7 @@ class GlobalNav extends React.PureComponent<Props, State> {
<GlobalNavExplore location={this.props.location} onSonarCloud={this.props.onSonarCloud} />
<li>
<EmbedDocsPopupHelper
currentUser={this.props.currentUser}
showTooltip={this.state.onboardingTutorialTooltip}
suggestions={this.props.suggestions}
tooltip={!this.props.onSonarCloud}

+ 0
- 6
server/sonar-web/src/main/js/app/styles/init/icons.css Переглянути файл

@@ -430,12 +430,6 @@ a:hover > .icon-radio {
}
}

.icon-help:before {
content: '\f059';
color: var(--blue);
font-size: var(--bigFontSize);
}

.icon-close:before {
content: '\f00d';
font-size: var(--bigFontSize);

+ 2
- 0
server/sonar-web/src/main/js/app/utils/exposeLibraries.ts Переглянути файл

@@ -32,6 +32,7 @@ import LicenseEditionSet from '../../apps/marketplace/components/LicenseEditionS
import HomePageSelect from '../../components/controls/HomePageSelect';
import ListFooter from '../../components/controls/ListFooter';
import Modal from '../../components/controls/Modal';
import HelpTooltip from '../../components/controls/HelpTooltip';
import SearchBox from '../../components/controls/SearchBox';
import Select from '../../components/controls/Select';
import Tooltip from '../../components/controls/Tooltip';
@@ -60,6 +61,7 @@ const exposeLibraries = () => {
DuplicationsRating,
EditButton,
FavoriteContainer,
HelpTooltip,
HomePageSelect,
Level,
LicenseEditionSet,

+ 17
- 19
server/sonar-web/src/main/js/apps/background-tasks/components/NoWorkersSupportPopup.tsx Переглянути файл

@@ -18,27 +18,25 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import BubblePopup from '../../../components/common/BubblePopup';
import { translate } from '../../../helpers/l10n';

interface Props {
popupPosition?: any;
}

export default function NoWorkersSupportPopup(props: Props) {
export default function NoWorkersSupportPopup() {
return (
<BubblePopup position={props.popupPosition} customClass="bubble-popup-bottom-right">
<div className="abs-width-400">
<h6 className="spacer-bottom">{translate('background_tasks.add_more_workers')}</h6>
<p className="big-spacer-bottom markdown">
{translate('background_tasks.add_more_workers.text')}
</p>
<p>
<a href="https://redirect.sonarsource.com/editions/enterprise.html" target="_blank">
{translate('learn_more')}
</a>
</p>
</div>
</BubblePopup>
<>
<p className="spacer-bottom">
<strong>{translate('background_tasks.add_more_workers')}</strong>
</p>
<p className="big-spacer-bottom markdown">
{translate('background_tasks.add_more_workers.text')}
</p>
<p>
<a
href="https://redirect.sonarsource.com/editions/enterprise.html"
rel="noopener noreferrer"
target="_blank">
{translate('learn_more')}
</a>
</p>
</>
);
}

+ 5
- 20
server/sonar-web/src/main/js/apps/background-tasks/components/Workers.tsx Переглянути файл

@@ -21,10 +21,8 @@ import * as React from 'react';
import WorkersForm from './WorkersForm';
import NoWorkersSupportPopup from './NoWorkersSupportPopup';
import AlertWarnIcon from '../../../components/icons-components/AlertWarnIcon';
import BubblePopupHelper from '../../../components/common/BubblePopupHelper';
import HelpIcon from '../../../components/icons-components/HelpIcon';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import Tooltip from '../../../components/controls/Tooltip';
import * as theme from '../../../app/theme';
import { getWorkers } from '../../../api/ce';
import { translate } from '../../../helpers/l10n';
import { EditButton } from '../../../components/ui/buttons';
@@ -103,15 +101,12 @@ export default class Workers extends React.PureComponent<{}, State> {
const { canSetWorkerCount, formOpen, loading, workerCount } = this.state;

return (
<div>
<div className="display-flex-center">
{!loading &&
workerCount > 1 && (
<Tooltip overlay={translate('background_tasks.number_of_workers.warning')}>
<span>
<AlertWarnIcon
className="little-spacer-right bt-workers-warning-icon"
fill="#d3d3d3"
/>
<span className="display-inline-flex-center little-spacer-right">
<AlertWarnIcon fill="#d3d3d3" />
</span>
</Tooltip>
)}
@@ -138,17 +133,7 @@ export default class Workers extends React.PureComponent<{}, State> {

{!loading &&
!canSetWorkerCount && (
<span className="spacer-left">
<a className="link-no-underline" href="#" onClick={this.handleHelpClick}>
<HelpIcon className="text-text-bottom" fill={theme.gray80} />
</a>
<BubblePopupHelper
isOpen={this.state.noSupportPopup}
popup={<NoWorkersSupportPopup />}
position="bottomright"
togglePopup={this.toggleNoSupportPopup}
/>
</span>
<HelpTooltip className="spacer-left" overlay={<NoWorkersSupportPopup />} />
)}

{formOpen && <WorkersForm onClose={this.closeForm} workerCount={this.state.workerCount} />}

+ 36
- 33
server/sonar-web/src/main/js/apps/background-tasks/components/__tests__/__snapshots__/Workers-test.tsx.snap Переглянути файл

@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`opens form 1`] = `
<div>
<div
className="display-flex-center"
>
<span
className="text-middle"
>
@@ -24,7 +26,9 @@ exports[`opens form 1`] = `
`;

exports[`opens form 2`] = `
<div>
<div
className="display-flex-center"
>
<span
className="text-middle"
>
@@ -51,7 +55,9 @@ exports[`opens form 2`] = `
`;

exports[`renders 1`] = `
<div>
<div
className="display-flex-center"
>
<span
className="text-middle"
>
@@ -64,7 +70,9 @@ exports[`renders 1`] = `
`;

exports[`renders 2`] = `
<div>
<div
className="display-flex-center"
>
<span
className="text-middle"
>
@@ -87,13 +95,16 @@ exports[`renders 2`] = `
`;

exports[`renders 3`] = `
<div>
<div
className="display-flex-center"
>
<Tooltip
overlay="background_tasks.number_of_workers.warning"
>
<span>
<span
className="display-inline-flex-center little-spacer-right"
>
<AlertWarnIcon
className="little-spacer-right bt-workers-warning-icon"
fill="#d3d3d3"
/>
</span>
@@ -120,13 +131,16 @@ exports[`renders 3`] = `
`;

exports[`renders 4`] = `
<div>
<div
className="display-flex-center"
>
<Tooltip
overlay="background_tasks.number_of_workers.warning"
>
<span>
<span
className="display-inline-flex-center little-spacer-right"
>
<AlertWarnIcon
className="little-spacer-right bt-workers-warning-icon"
fill="#d3d3d3"
/>
</span>
@@ -141,31 +155,17 @@ exports[`renders 4`] = `
2
</strong>
</span>
<span
<HelpTooltip
className="spacer-left"
>
<a
className="link-no-underline"
href="#"
onClick={[Function]}
>
<HelpIcon
className="text-text-bottom"
fill="#cdcdcd"
/>
</a>
<BubblePopupHelper
isOpen={false}
popup={<NoWorkersSupportPopup />}
position="bottomright"
togglePopup={[Function]}
/>
</span>
overlay={<NoWorkersSupportPopup />}
/>
</div>
`;

exports[`updates worker count 1`] = `
<div>
<div
className="display-flex-center"
>
<span
className="text-middle"
>
@@ -192,13 +192,16 @@ exports[`updates worker count 1`] = `
`;

exports[`updates worker count 2`] = `
<div>
<div
className="display-flex-center"
>
<Tooltip
overlay="background_tasks.number_of_workers.warning"
>
<span>
<span
className="display-inline-flex-center little-spacer-right"
>
<AlertWarnIcon
className="little-spacer-right bt-workers-warning-icon"
fill="#d3d3d3"
/>
</span>

+ 3
- 8
server/sonar-web/src/main/js/apps/component-measures/drilldown/BubbleChart.js Переглянути файл

@@ -22,8 +22,7 @@ import React from 'react';
import EmptyResult from './EmptyResult';
import OriginalBubbleChart from '../../../components/charts/BubbleChart';
import ColorRatingsLegend from '../../../components/charts/ColorRatingsLegend';
import Tooltip from '../../../components/controls/Tooltip';
import HelpIcon from '../../../components/icons-components/HelpIcon';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { formatMeasure, isDiffMetric } from '../../../helpers/measures';
import {
getLocalizedMetricDomain,
@@ -170,12 +169,8 @@ export default class BubbleChart extends React.PureComponent {
return (
<div className="measure-overview-bubble-chart-header">
<span className="measure-overview-bubble-chart-title">
{title}
<Tooltip overlay={this.getDescription(domain)}>
<span className="spacer-left text-info">
<HelpIcon />
</span>
</Tooltip>
<span className="text-middle">{title}</span>
<HelpTooltip className="spacer-left" overlay={this.getDescription(domain)} />
</span>
<span className="measure-overview-bubble-chart-legend">
<span className="note">

+ 5
- 2
server/sonar-web/src/main/js/apps/documentation/components/App.tsx Переглянути файл

@@ -27,6 +27,7 @@ import ScreenPositionHelper from '../../../components/common/ScreenPositionHelpe
import DocMarkdownBlock from '../../../components/docs/DocMarkdownBlock';
import DeferredSpinner from '../../../components/common/DeferredSpinner';
import { translate } from '../../../helpers/l10n';
import '../styles.css';

interface Props {
params: { splat?: string };
@@ -87,7 +88,7 @@ export default class App extends React.PureComponent<Props, State> {
return (
<div className="boxed-group">
<DocMarkdownBlock
className="cut-margins boxed-group-inner"
className="documentation-content cut-margins boxed-group-inner"
content={this.state.content}
displayH1={true}
/>
@@ -122,7 +123,9 @@ export default class App extends React.PureComponent<Props, State> {
</ScreenPositionHelper>

<div className="layout-page-main">
<div className="layout-page-main-inner">{this.renderContent()}</div>
<div className="layout-page-main-inner documentation-layout-inner">
{this.renderContent()}
</div>
</div>
</div>
);

server/sonar-web/src/main/js/app/components/nav/component/__tests__/NoBranchSupportPopup-test.tsx → server/sonar-web/src/main/js/apps/documentation/styles.css Переглянути файл

@@ -17,10 +17,11 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { shallow } from 'enzyme';
import NoBranchSupportPopup from '../NoBranchSupportPopup';
.documentation-layout-inner {
max-width: 740px;
}

it('renders', () => {
expect(shallow(<NoBranchSupportPopup />)).toMatchSnapshot();
});
.documentation-content > h1 {
margin-bottom: calc(4 * var(--gridSize));
font-size: 20px;
}

+ 6
- 5
server/sonar-web/src/main/js/apps/issues/components/BulkChangeModal.tsx Переглянути файл

@@ -28,7 +28,7 @@ import SearchSelect from '../../../components/controls/SearchSelect';
import Checkbox from '../../../components/controls/Checkbox';
import Modal from '../../../components/controls/Modal';
import Select from '../../../components/controls/Select';
import Tooltip from '../../../components/controls/Tooltip';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import SeverityHelper from '../../../components/shared/SeverityHelper';
import Avatar from '../../../components/ui/Avatar';
import { SubmitButton } from '../../../components/ui/buttons';
@@ -457,10 +457,11 @@ export default class BulkChangeModal extends React.PureComponent<Props, State> {
return (
<div className="modal-field">
<label htmlFor="comment">
{translate('issue.comment.formlink')}
<Tooltip overlay={translate('issue_bulk_change.comment.help')}>
<i className="icon-help little-spacer-left" />
</Tooltip>
<span className="text-middle">{translate('issue.comment.formlink')}</span>
<HelpTooltip
className="spacer-left"
overlay={translate('issue_bulk_change.comment.help')}
/>
</label>
<div>
<textarea

+ 8
- 9
server/sonar-web/src/main/js/apps/overview/qualityGate/QualityGate.js Переглянути файл

@@ -21,12 +21,10 @@
import React from 'react';
import QualityGateConditions from './QualityGateConditions';
import EmptyQualityGate from './EmptyQualityGate';
import * as theme from '../../../app/theme';
import { translate } from '../../../helpers/l10n';
import Level from '../../../components/ui/Level';
import Tooltip from '../../../components/controls/Tooltip';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import DocTooltip from '../../../components/docs/DocTooltip';
import HelpIcon from '../../../components/icons-components/HelpIcon';
/*:: import type { Component, MeasuresList } from '../types'; */

function parseQualityGateDetails(rawDetails /*: string */) {
@@ -73,12 +71,13 @@ export default function QualityGate({ branchLike, component, measures } /*: Prop

{ignoredConditions && (
<div className="alert alert-info display-inline-block big-spacer-top">
{translate('overview.quality_gate.ignored_conditions')}
<Tooltip overlay={translate('overview.quality_gate.ignored_conditions.tooltip')}>
<span className="spacer-left">
<HelpIcon fill={theme.blue} />
</span>
</Tooltip>
<span className="text-middle">
{translate('overview.quality_gate.ignored_conditions')}
</span>
<HelpTooltip
className="spacer-left"
overlay={translate('overview.quality_gate.ignored_conditions.tooltip')}
/>
</div>
)}


+ 8
- 11
server/sonar-web/src/main/js/apps/overview/qualityGate/__tests__/__snapshots__/QualityGate-test.js.snap Переглянути файл

@@ -25,18 +25,15 @@ exports[`renders message about ignored conditions 1`] = `
<div
className="alert alert-info display-inline-block big-spacer-top"
>
overview.quality_gate.ignored_conditions
<Tooltip
overlay="overview.quality_gate.ignored_conditions.tooltip"
<span
className="text-middle"
>
<span
className="spacer-left"
>
<HelpIcon
fill="#4b9fd5"
/>
</span>
</Tooltip>
overview.quality_gate.ignored_conditions
</span>
<HelpTooltip
className="spacer-left"
overlay="overview.quality_gate.ignored_conditions.tooltip"
/>
</div>
</div>
`;

+ 4
- 6
server/sonar-web/src/main/js/apps/permission-templates/components/ListHeader.js Переглянути файл

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

export default class ListHeader extends React.PureComponent {
@@ -42,11 +42,9 @@ export default class ListHeader extends React.PureComponent {

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


+ 3
- 4
server/sonar-web/src/main/js/apps/permissions/shared/components/PermissionHeader.tsx Переглянути файл

@@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import HelpTooltip from '../../../../components/controls/HelpTooltip';
import Tooltip from '../../../../components/controls/Tooltip';
import { translate, translateWithParameters } from '../../../../helpers/l10n';

@@ -69,13 +70,11 @@ export default class PermissionHeader extends React.PureComponent<Props> {
'global_permissions.filter_by_x_permission',
permission.name
)}>
<a href="#" onClick={this.handlePermissionClick}>
<a className="text-middle" href="#" onClick={this.handlePermissionClick}>
{permission.name}
</a>
</Tooltip>
<Tooltip overlay={this.renderTooltip(permission)}>
<i className="icon-help little-spacer-left" />
</Tooltip>
<HelpTooltip className="spacer-left" overlay={this.renderTooltip(permission)} />
</div>
</th>
);

+ 1
- 1
server/sonar-web/src/main/js/apps/permissions/styles.css Переглянути файл

@@ -29,5 +29,5 @@
}

.permissions-table .permission-column-inner {
width: 112px;
width: 100px;
}

+ 8
- 5
server/sonar-web/src/main/js/apps/projectBranches/components/App.tsx Переглянути файл

@@ -32,7 +32,7 @@ import {
import { translate } from '../../../helpers/l10n';
import { getValues } from '../../../api/settings';
import { formatMeasure } from '../../../helpers/measures';
import Tooltip from '../../../components/controls/Tooltip';
import HelpTooltip from '../../../components/controls/HelpTooltip';

interface Props {
branchLikes: BranchLike[];
@@ -154,10 +154,13 @@ export default class App extends React.PureComponent<Props, State> {
<React.Fragment key={getBranchLikeKey(branchLike)}>
{showOrphanHeader && (
<li className="dropdown-header">
{translate('branches.orphan_branches')}
<Tooltip overlay={translate('branches.orphan_branches.tooltip')}>
<i className="icon-help spacer-left" />
</Tooltip>
<div className="display-inline-block text-middle">
{translate('branches.orphan_branches')}
</div>
<HelpTooltip
className="spacer-left"
overlay={translate('branches.orphan_branches.tooltip')}
/>
</li>
)}
<BranchRow

+ 8
- 7
server/sonar-web/src/main/js/apps/projectBranches/components/__tests__/__snapshots__/App-test.tsx.snap Переглянути файл

@@ -150,14 +150,15 @@ exports[`renders sorted list of branches 1`] = `
<li
className="dropdown-header"
>
branches.orphan_branches
<Tooltip
overlay="branches.orphan_branches.tooltip"
<div
className="display-inline-block text-middle"
>
<i
className="icon-help spacer-left"
/>
</Tooltip>
branches.orphan_branches
</div>
<HelpTooltip
className="spacer-left"
overlay="branches.orphan_branches.tooltip"
/>
</li>
<BranchRow
branchLike={

+ 3
- 8
server/sonar-web/src/main/js/apps/projects/visualizations/Risk.tsx Переглянути файл

@@ -25,8 +25,7 @@ import { formatMeasure } from '../../../helpers/measures';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { RATING_COLORS } from '../../../helpers/constants';
import { getProjectUrl } from '../../../helpers/urls';
import Tooltip from '../../../components/controls/Tooltip';
import HelpIcon from '../../../components/icons-components/HelpIcon';
import HelpTooltip from '../../../components/controls/HelpTooltip';

const X_METRIC = 'sqale_index';
const X_METRIC_TYPE = 'SHORT_WORK_DUR';
@@ -138,12 +137,8 @@ export default class Risk extends React.PureComponent<Props> {
</div>
<div className="measure-details-bubble-chart-axis size">
<span className="measure-details-bubble-chart-title">
{translate('projects.visualization.risk')}
<Tooltip overlay={this.props.helpText}>
<span className="spacer-left text-info">
<HelpIcon />
</span>
</Tooltip>
<span className="text-middle">{translate('projects.visualization.risk')}</span>
<HelpTooltip className="spacer-left" overlay={this.props.helpText} />
</span>
<div>
<span className="spacer-right">

+ 3
- 8
server/sonar-web/src/main/js/apps/projects/visualizations/SimpleBubbleChart.tsx Переглянути файл

@@ -25,8 +25,7 @@ import { translate, translateWithParameters } from '../../../helpers/l10n';
import { RATING_COLORS } from '../../../helpers/constants';
import { getProjectUrl } from '../../../helpers/urls';
import { Project } from '../types';
import Tooltip from '../../../components/controls/Tooltip';
import HelpIcon from '../../../components/icons-components/HelpIcon';
import HelpTooltip from '../../../components/controls/HelpTooltip';

export interface Metric {
key: string;
@@ -129,12 +128,8 @@ export default class SimpleBubbleChart extends React.PureComponent<Props> {
</div>
<div className="measure-details-bubble-chart-axis size">
<span className="measure-details-bubble-chart-title">
{this.props.title}
<Tooltip overlay={this.props.helpText}>
<span className="spacer-left text-info">
<HelpIcon className="text-bottom" />
</span>
</Tooltip>
<span className="text-middle">{this.props.title}</span>
<HelpTooltip className="spacer-left" overlay={this.props.helpText} />
</span>
<div>
{colorMetric != null && (

+ 8
- 9
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/Risk-test.tsx.snap Переглянути файл

@@ -100,16 +100,15 @@ exports[`renders 1`] = `
<span
className="measure-details-bubble-chart-title"
>
projects.visualization.risk
<Tooltip
overlay="foobar"
<span
className="text-middle"
>
<span
className="spacer-left text-info"
>
<HelpIcon />
</span>
</Tooltip>
projects.visualization.risk
</span>
<HelpTooltip
className="spacer-left"
overlay="foobar"
/>
</span>
<div>
<span

+ 6
- 10
server/sonar-web/src/main/js/apps/projects/visualizations/__tests__/__snapshots__/SimpleBubbleChart-test.tsx.snap Переглянути файл

@@ -89,17 +89,13 @@ exports[`renders 1`] = `
<span
className="measure-details-bubble-chart-title"
>
<Tooltip
<span
className="text-middle"
/>
<HelpTooltip
className="spacer-left"
overlay="foobar"
>
<span
className="spacer-left text-info"
>
<HelpIcon
className="text-bottom"
/>
</span>
</Tooltip>
/>
</span>
<div>
<span

+ 6
- 5
server/sonar-web/src/main/js/apps/projectsManagement/Search.tsx Переглянути файл

@@ -26,7 +26,7 @@ import { Organization } from '../../app/types';
import Checkbox from '../../components/controls/Checkbox';
import { translate } from '../../helpers/l10n';
import QualifierIcon from '../../components/shared/QualifierIcon';
import Tooltip from '../../components/controls/Tooltip';
import HelpTooltip from '../../components/controls/HelpTooltip';
import DateInput from '../../components/controls/DateInput';
import Select from '../../components/controls/Select';
import SearchBox from '../../components/controls/SearchBox';
@@ -156,13 +156,14 @@ export default class Search extends React.PureComponent<Props, State> {
className="link-checkbox-control"
id="projects-provisioned"
onCheck={this.props.onProvisionedChanged}>
<span className="little-spacer-left">
<span className="text-middle little-spacer-left">
{translate('provisioning.only_provisioned')}
<Tooltip overlay={translate('provisioning.only_provisioned.tooltip')}>
<i className="spacer-left icon-help" />
</Tooltip>
</span>
</Checkbox>
<HelpTooltip
className="spacer-left"
overlay={translate('provisioning.only_provisioned.tooltip')}
/>
</td>
) : null;


+ 10
- 16
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/Search-test.tsx.snap Переглянути файл

@@ -101,18 +101,15 @@ exports[`render qualifiers filter 1`] = `
thirdState={false}
>
<span
className="little-spacer-left"
className="text-middle little-spacer-left"
>
provisioning.only_provisioned
<Tooltip
overlay="provisioning.only_provisioned.tooltip"
>
<i
className="spacer-left icon-help"
/>
</Tooltip>
</span>
</Checkbox>
<HelpTooltip
className="spacer-left"
overlay="provisioning.only_provisioned.tooltip"
/>
</td>
<td
className="text-middle"
@@ -188,18 +185,15 @@ exports[`renders 1`] = `
thirdState={false}
>
<span
className="little-spacer-left"
className="text-middle little-spacer-left"
>
provisioning.only_provisioned
<Tooltip
overlay="provisioning.only_provisioned.tooltip"
>
<i
className="spacer-left icon-help"
/>
</Tooltip>
</span>
</Checkbox>
<HelpTooltip
className="spacer-left"
overlay="provisioning.only_provisioned.tooltip"
/>
</td>
<td
className="text-middle"

+ 7
- 9
server/sonar-web/src/main/js/apps/quality-gates/components/BuiltInQualityGateBadge.tsx Переглянути файл

@@ -20,14 +20,14 @@
import * as React from 'react';
import * as classNames from 'classnames';
import Tooltip from '../../../components/controls/Tooltip';
import DocInclude from '../../../components/docs/DocInclude';
import { translate } from '../../../helpers/l10n';

interface Props {
className?: string;
tooltip?: boolean;
}

export default function BuiltInQualityGateBadge({ className, tooltip = true }: Props) {
export default function BuiltInQualityGateBadge({ className }: Props) {
const badge = (
<div className={classNames('outline-badge', className)}>
{translate('quality_gates.built_in')}
@@ -35,13 +35,11 @@ export default function BuiltInQualityGateBadge({ className, tooltip = true }: P
);

const overlay = (
<div>
<span>{translate('quality_gates.built_in.description.1')}</span>
<span className="little-spacer-left">
{translate('quality_gates.built_in.description.2')}
</span>
</div>
<DocInclude
className="abs-width-300 cut-margins"
path="/tooltips/quality-gates/built-in-quality-gate"
/>
);

return <Tooltip overlay={tooltip ? overlay : undefined}>{badge}</Tooltip>;
return <Tooltip overlay={overlay}>{badge}</Tooltip>;
}

+ 1
- 7
server/sonar-web/src/main/js/apps/quality-gates/components/DetailsHeader.tsx Переглянути файл

@@ -23,7 +23,6 @@ import RenameQualityGateForm from './RenameQualityGateForm';
import CopyQualityGateForm from './CopyQualityGateForm';
import DeleteQualityGateForm from './DeleteQualityGateForm';
import { fetchQualityGate, QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates';
import DocTooltip from '../../../components/docs/DocTooltip';
import { Button } from '../../../components/ui/buttons';
import { translate } from '../../../helpers/l10n';

@@ -76,12 +75,7 @@ export default class DetailsHeader extends React.PureComponent<Props, State> {
<div className="layout-page-main-inner">
<div className="pull-left display-flex-center">
<h2>{qualityGate.name}</h2>
{qualityGate.isBuiltIn && (
<>
<BuiltInQualityGateBadge className="spacer-left" />
<DocTooltip className="spacer-left" doc="quality-gates/built-in-quality-gate" />
</>
)}
{qualityGate.isBuiltIn && <BuiltInQualityGateBadge className="spacer-left" />}
</div>

<div className="pull-right">

+ 1
- 1
server/sonar-web/src/main/js/apps/quality-gates/components/List.js Переглянути файл

@@ -40,7 +40,7 @@ export default function List({ organization, qualityGates }) {
<td className="thin nowrap spacer-left text-right">
{qualityGate.isDefault && <span className="badge">{translate('default')}</span>}
{qualityGate.isBuiltIn && (
<BuiltInQualityGateBadge className="little-spacer-left" tooltip={false} />
<BuiltInQualityGateBadge className="little-spacer-left" />
)}
</td>
</tr>

+ 5
- 4
server/sonar-web/src/main/js/apps/quality-profiles/components/BuiltInQualityProfileBadge.tsx Переглянути файл

@@ -20,6 +20,7 @@
import * as React from 'react';
import * as classNames from 'classnames';
import Tooltip from '../../../components/controls/Tooltip';
import DocInclude from '../../../components/docs/DocInclude';
import { translate } from '../../../helpers/l10n';

interface Props {
@@ -35,10 +36,10 @@ export default function BuiltInQualityProfileBadge({ className, tooltip = true }
);

const overlay = (
<span>
{translate('quality_profiles.built_in.description.1')}{' '}
{translate('quality_profiles.built_in.description.2')}
</span>
<DocInclude
className="abs-width-300 cut-margins"
path="/tooltips/quality-profiles/built-in-quality-profile"
/>
);

return <Tooltip overlay={tooltip ? overlay : undefined}>{badge}</Tooltip>;

+ 7
- 5
server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileInheritanceBox.tsx Переглянути файл

@@ -20,7 +20,7 @@
import * as React from 'react';
import ProfileLink from '../components/ProfileLink';
import BuiltInQualityProfileBadge from '../components/BuiltInQualityProfileBadge';
import Tooltip from '../../../components/controls/Tooltip';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { translate, translateWithParameters } from '../../../helpers/l10n';

interface Props {
@@ -50,19 +50,21 @@ export default function ProfileInheritanceBox({ displayLink = true, ...props }:
<div style={{ paddingLeft: offset }}>
{displayLink ? (
<ProfileLink
className="text-middle"
language={props.language}
name={profile.name}
organization={props.organization}>
{profile.name}
</ProfileLink>
) : (
profile.name
<span className="text-middle">{profile.name}</span>
)}
{profile.isBuiltIn && <BuiltInQualityProfileBadge className="spacer-left" />}
{extendsBuiltIn && (
<Tooltip overlay={translate('quality_profiles.extends_built_in')}>
<i className="icon-help spacer-left" />
</Tooltip>
<HelpTooltip
className="spacer-left"
overlay={translate('quality_profiles.extends_built_in')}
/>
)}
</div>
</td>

+ 6
- 5
server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesDeprecatedWarning.tsx Переглянути файл

@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { Link } from 'react-router';
import Tooltip from '../../../components/controls/Tooltip';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';

@@ -33,10 +33,11 @@ export default function ProfileRulesDeprecatedWarning(props: Props) {
return (
<div className="quality-profile-rules-deprecated clearfix">
<span className="pull-left">
{translate('quality_profiles.deprecated_rules')}
<Tooltip overlay={translate('quality_profiles.deprecated_rules_description')}>
<i className="icon-help spacer-left" />
</Tooltip>
<span className="text-middle">{translate('quality_profiles.deprecated_rules')}</span>
<HelpTooltip
className="spacer-left"
overlay={translate('quality_profiles.deprecated_rules_description')}
/>
</span>
<Link
className="pull-right"

+ 7
- 6
server/sonar-web/src/main/js/apps/quality-profiles/details/ProfileRulesSonarWayComparison.tsx Переглянути файл

@@ -19,7 +19,7 @@
*/
import * as React from 'react';
import { Link } from 'react-router';
import Tooltip from '../../../components/controls/Tooltip';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { getRulesUrl } from '../../../helpers/urls';
import { translate } from '../../../helpers/l10n';

@@ -45,12 +45,13 @@ export default function ProfileRulesSonarWayComparison(props: Props) {
return (
<div className="quality-profile-rules-sonarway-missing clearfix">
<span className="pull-left">
{translate('quality_profiles.sonarway_missing_rules')}
<Tooltip overlay={translate('quality_profiles.sonarway_missing_rules_description')}>
<i className="icon-help spacer-left" />
</Tooltip>
<span className="text-middle">{translate('quality_profiles.sonarway_missing_rules')}</span>
<HelpTooltip
className="spacer-left"
overlay={translate('quality_profiles.sonarway_missing_rules_description')}
/>
</span>
<Link className="pull-right" to={url}>
<Link className="pull-right" data-test="rules" to={url}>
{props.sonarWayMissingRules}
</Link>
</div>

+ 8
- 7
server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesDeprecatedWarning-test.tsx.snap Переглянути файл

@@ -7,14 +7,15 @@ exports[`should render correctly 1`] = `
<span
className="pull-left"
>
quality_profiles.deprecated_rules
<Tooltip
overlay="quality_profiles.deprecated_rules_description"
<span
className="text-middle"
>
<i
className="icon-help spacer-left"
/>
</Tooltip>
quality_profiles.deprecated_rules
</span>
<HelpTooltip
className="spacer-left"
overlay="quality_profiles.deprecated_rules_description"
/>
</span>
<Link
className="pull-right"

+ 9
- 7
server/sonar-web/src/main/js/apps/quality-profiles/details/__tests__/__snapshots__/ProfileRulesSonarWayComparison-test.tsx.snap Переглянути файл

@@ -7,17 +7,19 @@ exports[`should render correctly 1`] = `
<span
className="pull-left"
>
quality_profiles.sonarway_missing_rules
<Tooltip
overlay="quality_profiles.sonarway_missing_rules_description"
<span
className="text-middle"
>
<i
className="icon-help spacer-left"
/>
</Tooltip>
quality_profiles.sonarway_missing_rules
</span>
<HelpTooltip
className="spacer-left"
overlay="quality_profiles.sonarway_missing_rules_description"
/>
</span>
<Link
className="pull-right"
data-test="rules"
onlyActiveOnIndex={false}
style={Object {}}
to={

+ 10
- 10
server/sonar-web/src/main/js/apps/quality-profiles/home/ProfilesListRow.tsx Переглянути файл

@@ -28,7 +28,7 @@ import { getRulesUrl } from '../../../helpers/urls';
import { isStagnant } from '../utils';
import { Profile } from '../types';
import Tooltip from '../../../components/controls/Tooltip';
import DocTooltip from '../../../components/docs/DocTooltip';
import DocInclude from '../../../components/docs/DocInclude';

interface Props {
onRequestFail: (reason: any) => void;
@@ -51,12 +51,7 @@ export default class ProfilesListRow extends React.PureComponent<Props> {
{profile.name}
</ProfileLink>
</div>
{profile.isBuiltIn && (
<>
<BuiltInQualityProfileBadge className="spacer-left" />
<DocTooltip className="spacer-left" doc="quality-profiles/built-in-quality-profile" />
</>
)}
{profile.isBuiltIn && <BuiltInQualityProfileBadge className="spacer-left" />}
</div>
);
}
@@ -66,10 +61,15 @@ export default class ProfilesListRow extends React.PureComponent<Props> {

if (profile.isDefault) {
return (
<>
<Tooltip
overlay={
<DocInclude
className="abs-width-300 cut-margins"
path="/tooltips/quality-profiles/default-quality-profile"
/>
}>
<span className="badge">{translate('default')}</span>
<DocTooltip className="table-cell-doc" doc="quality-profiles/default-quality-profile" />
</>
</Tooltip>
);
}


+ 2
- 2
server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.css Переглянути файл

@@ -63,8 +63,8 @@

.oauth-providers-help {
position: absolute;
top: 12px;
right: -32px;
top: 15px;
right: -24px;
}

.oauth-providers + .login-form {

+ 2
- 8
server/sonar-web/src/main/js/apps/sessions/components/OAuthProviders.tsx Переглянути файл

@@ -20,10 +20,8 @@
import * as React from 'react';
import * as classNames from 'classnames';
import { translateWithParameters } from '../../../helpers/l10n';
import * as theme from '../../../app/theme';
import { IdentityProvider } from '../../../app/types';
import Tooltip from '../../../components/controls/Tooltip';
import HelpIcon from '../../../components/icons-components/HelpIcon';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { isDarkColor } from '../../../helpers/colors';
import { getBaseUrl } from '../../../helpers/urls';
import './OAuthProviders.css';
@@ -80,11 +78,7 @@ function OAuthProvider({ format, identityProvider, returnTo }: ItemProps) {
<span>{format(identityProvider.name)}</span>
</a>
{identityProvider.helpMessage && (
<Tooltip overlay={identityProvider.helpMessage}>
<div className="oauth-providers-help">
<HelpIcon fill={theme.blue} />
</div>
</Tooltip>
<HelpTooltip className="oauth-providers-help" overlay={identityProvider.helpMessage} />
)}
</li>
);

+ 3
- 10
server/sonar-web/src/main/js/apps/sessions/components/__tests__/__snapshots__/OAuthProviders-test.tsx.snap Переглянути файл

@@ -81,17 +81,10 @@ exports[`should render correctly 3`] = `
login.login_with_x.Bar
</span>
</a>
<Tooltip
<HelpTooltip
className="oauth-providers-help"
overlay="Help message!"
>
<div
className="oauth-providers-help"
>
<HelpIcon
fill="#4b9fd5"
/>
</div>
</Tooltip>
/>
</li>
`;


+ 11
- 14
server/sonar-web/src/main/js/apps/web-api/components/Search.tsx Переглянути файл

@@ -19,8 +19,7 @@
*/
import * as React from 'react';
import Checkbox from '../../../components/controls/Checkbox';
import HelpIcon from '../../../components/icons-components/HelpIcon';
import Tooltip from '../../../components/controls/Tooltip';
import HelpTooltip from '../../../components/controls/HelpTooltip';
import { translate } from '../../../helpers/l10n';
import SearchBox from '../../../components/controls/SearchBox';

@@ -42,27 +41,25 @@ export default function Search(props: Props) {
</div>

<div className="big-spacer-top">
<Checkbox checked={showInternal} onCheck={onToggleInternal}>
<Checkbox checked={showInternal} className="text-middle" onCheck={onToggleInternal}>
<span className="little-spacer-left">{translate('api_documentation.show_internal')}</span>
</Checkbox>
<Tooltip overlay={translate('api_documentation.internal_tooltip')}>
<span>
<HelpIcon className="spacer-left text-info" />
</span>
</Tooltip>
<HelpTooltip
className="spacer-left"
overlay={translate('api_documentation.internal_tooltip')}
/>
</div>

<div className="spacer-top">
<Checkbox checked={showDeprecated} onCheck={onToggleDeprecated}>
<Checkbox checked={showDeprecated} className="text-middle" onCheck={onToggleDeprecated}>
<span className="little-spacer-left">
{translate('api_documentation.show_deprecated')}
</span>
</Checkbox>
<Tooltip overlay={translate('api_documentation.deprecation_tooltip')}>
<span>
<HelpIcon className="spacer-left text-info" />
</span>
</Tooltip>
<HelpTooltip
className="spacer-left"
overlay={translate('api_documentation.deprecation_tooltip')}
/>
</div>
</div>
);

+ 8
- 16
server/sonar-web/src/main/js/apps/web-api/components/__tests__/__snapshots__/Search-test.tsx.snap Переглянути файл

@@ -15,6 +15,7 @@ exports[`should render correctly 1`] = `
>
<Checkbox
checked={false}
className="text-middle"
onCheck={[Function]}
thirdState={false}
>
@@ -24,21 +25,17 @@ exports[`should render correctly 1`] = `
api_documentation.show_internal
</span>
</Checkbox>
<Tooltip
<HelpTooltip
className="spacer-left"
overlay="api_documentation.internal_tooltip"
>
<span>
<HelpIcon
className="spacer-left text-info"
/>
</span>
</Tooltip>
/>
</div>
<div
className="spacer-top"
>
<Checkbox
checked={false}
className="text-middle"
onCheck={[Function]}
thirdState={false}
>
@@ -48,15 +45,10 @@ exports[`should render correctly 1`] = `
api_documentation.show_deprecated
</span>
</Checkbox>
<Tooltip
<HelpTooltip
className="spacer-left"
overlay="api_documentation.deprecation_tooltip"
>
<span>
<HelpIcon
className="spacer-left text-info"
/>
</span>
</Tooltip>
/>
</div>
</div>
`;

+ 2
- 6
server/sonar-web/src/main/js/apps/webhooks/components/PageHeader.tsx Переглянути файл

@@ -19,6 +19,7 @@
*/
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router';
import { translate } from '../../../helpers/l10n';

interface Props {
@@ -40,12 +41,7 @@ export default function PageHeader({ children, loading }: Props) {
id={'webhooks.description'}
values={{
url: (
<a
href="https://redirect.sonarsource.com/doc/webhooks.html"
rel="noopener noreferrer"
target="_blank">
{translate('webhooks.documentation_link')}
</a>
<Link to="/documentation/webhooks">{translate('webhooks.documentation_link')}</Link>
)
}}
/>

+ 5
- 5
server/sonar-web/src/main/js/apps/webhooks/components/__tests__/__snapshots__/PageHeader-test.tsx.snap Переглянути файл

@@ -21,13 +21,13 @@ exports[`should render correctly 1`] = `
id="webhooks.description"
values={
Object {
"url": <a
href="https://redirect.sonarsource.com/doc/webhooks.html"
rel="noopener noreferrer"
target="_blank"
"url": <Link
onlyActiveOnIndex={false}
style={Object {}}
to="/documentation/webhooks"
>
webhooks.documentation_link
</a>,
</Link>,
}
}
/>

+ 6
- 7
server/sonar-web/src/main/js/components/common/BranchStatus.tsx Переглянути файл

@@ -22,7 +22,7 @@ import StatusIndicator from './StatusIndicator';
import Level from '../ui/Level';
import BugIcon from '../icons-components/BugIcon';
import CodeSmellIcon from '../icons-components/CodeSmellIcon';
import HelpIcon from '../icons-components/HelpIcon';
import HelpTooltip from '../controls/HelpTooltip';
import Tooltip from '../controls/Tooltip';
import VulnerabilityIcon from '../icons-components/VulnerabilityIcon';
import { BranchLike } from '../../app/types';
@@ -81,15 +81,14 @@ export default function BranchStatus({ branchLike, concise = false }: Props) {
<CodeSmellIcon className="little-spacer-left" />
</li>
{shouldDisplayHelper && (
<Tooltip
<HelpTooltip
className="spacer-left"
overlay={translateWithParameters(
'branches.short_lived.quality_gate.description',
totalIssues
)}>
<li className="spacer-left">
<HelpIcon className="text-info" />
</li>
</Tooltip>
)}
tagName="li"
/>
)}
</ul>
);

+ 4
- 10
server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/BranchStatus-test.tsx.snap Переглянути файл

@@ -167,16 +167,10 @@ exports[`renders status of short-living branches 4`] = `
className="little-spacer-left"
/>
</li>
<Tooltip
<HelpTooltip
className="spacer-left"
overlay="branches.short_lived.quality_gate.description.1"
>
<li
className="spacer-left"
>
<HelpIcon
className="text-info"
/>
</li>
</Tooltip>
tagName="li"
/>
</ul>
`;

server/sonar-web/src/main/js/app/components/nav/component/__tests__/SingleBranchHelperPopup-test.tsx → server/sonar-web/src/main/js/components/controls/HelpTooltip.css Переглянути файл

@@ -17,10 +17,15 @@
* 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 SingleBranchHelperPopup from '../SingleBranchHelperPopup';
.help-tooltip {
display: inline-flex;
align-items: center;
vertical-align: middle;
}

it('renders', () => {
expect(shallow(<SingleBranchHelperPopup />)).toMatchSnapshot();
});
.help-toolip-link {
display: block;
width: 12px;
height: 12px;
border: none;
}

server/sonar-web/src/main/js/app/components/nav/component/NoBranchSupportPopup.tsx → server/sonar-web/src/main/js/components/controls/HelpTooltip.tsx Переглянути файл

@@ -18,21 +18,28 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { translate } from '../../../../helpers/l10n';
import * as classNames from 'classnames';
import Tooltip from './Tooltip';
import HelpIcon from '../icons-components/HelpIcon';
import * as theme from '../../app/theme';
import './HelpTooltip.css';

export default function NoBranchSupportPopup() {
return (
<>
<h6 className="spacer-bottom">{translate('branches.no_support.header')}</h6>
<p className="big-spacer-bottom markdown">{translate('branches.no_support.header.text')}</p>
<p>
<a
href="https://redirect.sonarsource.com/editions/developer.html"
rel="noopener noreferrer"
target="_blank">
{translate('learn_more')}
</a>
</p>
</>
interface Props {
className?: string;
children?: React.ReactNode;
onShow?: () => void;
overlay: React.ReactNode;
tagName?: string;
}

export default function HelpTooltip(props: Props) {
const { children = <HelpIcon fill={theme.gray71} size={12} />, tagName = 'div' } = props;

return React.createElement(
tagName,
{ className: classNames('help-tooltip', props.className) },
<Tooltip mouseLeaveDelay={0.25} onShow={props.onShow} overlay={props.overlay}>
<span className="display-inline-flex-center">{children}</span>
</Tooltip>
);
}

+ 0
- 73
server/sonar-web/src/main/js/components/controls/Popup.tsx Переглянути файл

@@ -1,73 +0,0 @@
/*
* 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 OutsideClickHandler from './OutsideClickHandler';
import Tooltip from './Tooltip';

interface Props {
children: (props: { onClick: () => void }) => React.ReactElement<any>;
overlay: React.ReactNode;
}

interface State {
visible: boolean;
}

export default class Popup extends React.Component<Props, State> {
state: State = { visible: false };

componentWillReceiveProps(nextProps: Props) {
if (nextProps.overlay !== this.props.overlay) {
this.setState({ visible: false });
}
}

handleClick = (event?: React.MouseEvent<HTMLElement>) => {
if (event) {
event.preventDefault();
event.currentTarget.blur();
}

// defer opening to not trigger OutsideClickHandler.onClickOutside callback
setTimeout(() => {
this.setState({ visible: true });
}, 0);
};

handleClickOutside = () => {
this.setState({ visible: false });
};

renderOverlay() {
return (
<OutsideClickHandler onClickOutside={this.handleClickOutside}>
{({ ref }) => <div ref={ref}>{this.props.overlay}</div>}
</OutsideClickHandler>
);
}

render() {
return (
<Tooltip classNameSpace="popup" overlay={this.renderOverlay()} visible={this.state.visible}>
{this.props.children({ onClick: this.handleClick })}
</Tooltip>
);
}
}

+ 18
- 82
server/sonar-web/src/main/js/components/controls/Tooltip.css Переглянути файл

@@ -17,8 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
.tooltip,
.popup {
.tooltip {
position: absolute;
z-index: var(--tooltipZIndex);
display: block;
@@ -33,37 +32,27 @@
animation: fadeIn 0.3s forwards;
}

.popup {
font-size: var(--baseFontSize);
font-weight: normal;
}

.tooltip.top,
.popup.top {
.tooltip.top {
padding: 5px 0;
margin-top: -3px;
}

.tooltip.right,
.popup.right {
.tooltip.right {
padding: 0 5px;
margin-left: 3px;
}

.tooltip.bottom,
.popup.bottom {
.tooltip.bottom {
padding: 5px 0;
margin-top: 3px;
}

.tooltip.left,
.popup.left {
.tooltip.left {
padding: 0 5px;
margin-left: -3px;
}

.tooltip-inner,
.popup-inner {
.tooltip-inner {
max-width: 300px;
text-align: left;
text-decoration: none;
@@ -73,41 +62,34 @@
}

.tooltip-inner {
padding: 3px 8px;
padding: 12px 17px;
color: #fff;
background-color: #475760;
letter-spacing: 0.04em;
}

.popup-inner {
padding: calc(2 * var(--gridSize));
border: 1px solid var(--barBorderColor);
color: var(--baseFontColor);
background-color: #fff;
box-shadow: var(--defaultShadow);
}

.tooltip-inner .alert {
margin-bottom: 5px;
border-radius: 4px;
}

.tooltip-inner a {
color: var(--lightBlue);
border-bottom-color: #8da6b3;
color: #a5d0ea;
}

.tooltip-inner hr {
background-color: #5d6d75;
}

.tooltip-arrow,
.popup-arrow,
.popup-arrow::after {
.tooltip-arrow {
position: absolute;
width: 0;
height: 0;
border: solid transparent;
}

.tooltip.top .tooltip-arrow,
.popup.top .popup-arrow,
.popup.top .popup-arrow::after {
.tooltip.top .tooltip-arrow {
bottom: 0;
left: 50%;
border-width: 5px 5px 0;
@@ -118,19 +100,7 @@
border-top-color: #475760;
}

.popup.top .popup-arrow {
border-top-color: var(--barBorderColor);
}

.popup.top .popup-arrow::after {
content: '';
border-top-color: #fff;
transform: translateX(-5px) translateY(-1px);
}

.tooltip.right .tooltip-arrow,
.popup.right .popup-arrow,
.popup.right .popup-arrow::after {
.tooltip.right .tooltip-arrow {
top: 50%;
left: 0;
transform: translateY(-5px);
@@ -142,19 +112,7 @@
border-right-color: #475760;
}

.popup.right .popup-arrow {
border-right-color: var(--barBorderColor);
}

.popup.right .popup-arrow::after {
content: '';
border-right-color: #fff;
transform: translateY(-5px) translateX(1px);
}

.tooltip.left .tooltip-arrow,
.popup.left .popup-arrow,
.popup.left .popup-arrow::after {
.tooltip.left .tooltip-arrow {
top: 50%;
right: 0;
transform: translateY(-5px);
@@ -166,19 +124,7 @@
border-left-color: #475760;
}

.popup.left .popup-arrow {
border-left-color: var(--barBorderColor);
}

.popup.left .popup-arrow::after {
content: '';
border-left-color: #fff;
transform: translateY(-5px) translateX(-1px);
}

.tooltip.bottom .tooltip-arrow,
.popup.bottom .popup-arrow,
.popup.bottom .popup-arrow::after {
.tooltip.bottom .tooltip-arrow {
top: 0;
left: 50%;
transform: translateX(-5px);
@@ -190,16 +136,6 @@
border-bottom-color: #475760;
}

.popup.bottom .popup-arrow {
border-bottom-color: var(--barBorderColor);
}

.popup.bottom .popup-arrow::after {
content: '';
border-bottom-color: #fff;
transform: translateX(-5px) translateY(1px);
}

@keyframes fadeIn {
from {
opacity: 0;

+ 32
- 5
server/sonar-web/src/main/js/components/controls/Tooltip.tsx Переглянути файл

@@ -28,6 +28,7 @@ interface Props {
classNameSpace?: string;
children: React.ReactElement<{}>;
mouseEnterDelay?: number;
mouseLeaveDelay?: number;
onShow?: () => void;
onHide?: () => void;
overlay: React.ReactNode;
@@ -65,8 +66,10 @@ export default function Tooltip(props: Props) {
export class TooltipInner extends React.Component<Props, State> {
throttledPositionTooltip: (() => void);
mouseEnterInterval?: number;
mouseLeaveInterval?: number;
tooltipNode?: HTMLElement | null;
mounted = false;
mouseIn = false;

static defaultProps = {
mouseEnterDelay: 0.1
@@ -113,6 +116,7 @@ export class TooltipInner extends React.Component<Props, State> {
componentWillUnmount() {
this.mounted = false;
this.removeEventListeners();
this.clearIntervals();
}

addEventListeners = () => {
@@ -125,6 +129,11 @@ export class TooltipInner extends React.Component<Props, State> {
window.removeEventListener('scroll', this.throttledPositionTooltip);
};

clearIntervals = () => {
window.clearInterval(this.mouseEnterInterval);
window.clearInterval(this.mouseLeaveInterval);
};

isVisible = () => {
return this.props.visible !== undefined ? this.props.visible : this.state.visible;
};
@@ -235,15 +244,31 @@ export class TooltipInner extends React.Component<Props, State> {
window.clearInterval(this.mouseEnterInterval);
this.mouseEnterInterval = undefined;
}
if (this.props.visible === undefined) {
this.setState({ visible: false });
}

if (this.props.onHide) {
this.props.onHide();
if (!this.mouseIn) {
this.mouseLeaveInterval = window.setTimeout(() => {
if (this.mounted) {
if (this.props.visible === undefined && !this.mouseIn) {
this.setState({ visible: false });
}
}
}, (this.props.mouseLeaveDelay || 0) * 1000);

if (this.props.onHide) {
this.props.onHide();
}
}
};

handleOverlayMouseEnter = () => {
this.mouseIn = true;
};

handleOverlayMouseLeave = () => {
this.mouseIn = false;
this.handleMouseLeave();
};

render() {
const { classNameSpace = 'tooltip' } = this.props;

@@ -257,6 +282,8 @@ export class TooltipInner extends React.Component<Props, State> {
<TooltipPortal>
<div
className={`${classNameSpace} ${this.getPlacement()}`}
onMouseEnter={this.handleOverlayMouseEnter}
onMouseLeave={this.handleOverlayMouseLeave}
ref={this.tooltipNodeRef}
style={
isMeasured(this.state)

+ 2
- 0
server/sonar-web/src/main/js/components/controls/__tests__/Tooltip-test.tsx Переглянути файл

@@ -56,6 +56,8 @@ it('should open & close', () => {
expect(onShow).toBeCalled();

wrapper.find('#tooltip').simulate('mouseleave');
jest.runOnlyPendingTimers();
wrapper.update();
expect(wrapper).toMatchSnapshot();
expect(onHide).toBeCalled();
});

+ 4
- 0
server/sonar-web/src/main/js/components/controls/__tests__/__snapshots__/Tooltip-test.tsx.snap Переглянути файл

@@ -10,6 +10,8 @@ exports[`should open & close 1`] = `
<TooltipPortal>
<div
className="tooltip bottom"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
<div
className="tooltip-inner"
@@ -56,6 +58,8 @@ exports[`should render 2`] = `
<TooltipPortal>
<div
className="tooltip bottom"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
>
<div
className="tooltip-inner"

+ 10
- 2
server/sonar-web/src/main/js/components/docs/DocImg.tsx Переглянути файл

@@ -18,13 +18,21 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import { getBaseUrl } from '../../helpers/urls';

export default function DocImg(props: React.ImgHTMLAttributes<HTMLImageElement>) {
const { alt, src, ...other } = props;

if (process.env.NODE_ENV === 'development') {
return <img alt={alt} className="max-width-100" src={src} {...other} />;
return <img alt={alt} className="max-width-100" src={getBaseUrl() + src} {...other} />;
}

return <img alt={alt} className="max-width-100" src={'/images/embed-doc' + src} {...other} />;
return (
<img
alt={alt}
className="max-width-100"
src={getBaseUrl() + '/images/embed-doc' + src}
{...other}
/>
);
}

+ 2
- 1
server/sonar-web/src/main/js/components/docs/DocInclude.tsx Переглянути файл

@@ -21,6 +21,7 @@ import * as React from 'react';
import DocMarkdownBlock from './DocMarkdownBlock';

interface Props {
className?: string;
path: string;
}

@@ -67,6 +68,6 @@ export default class DocInclude extends React.PureComponent<Props, State> {
};

render() {
return <DocMarkdownBlock content={this.state.content} />;
return <DocMarkdownBlock className={this.props.className} content={this.state.content} />;
}
}

+ 10
- 3
server/sonar-web/src/main/js/components/docs/DocLink.tsx Переглянути файл

@@ -19,6 +19,7 @@
*/
import * as React from 'react';
import { Link } from 'react-router';
import DetachIcon from '../../components/icons-components/DetachIcon';

export default function DocLink(props: React.AnchorHTMLAttributes<HTMLAnchorElement>) {
const { children, href, ...other } = props;
@@ -32,8 +33,14 @@ export default function DocLink(props: React.AnchorHTMLAttributes<HTMLAnchorElem
}

return (
<a href={href} {...other}>
{children}
</a>
<>
<a className="text-middle" href={href} rel="noopener noreferrer" target="_blank" {...other}>
{children}
</a>
<DetachIcon
className="text-middle text-muted little-spacer-left little-spacer-right"
size={12}
/>
</>
);
}

+ 9
- 44
server/sonar-web/src/main/js/components/docs/DocTooltip.tsx Переглянути файл

@@ -18,15 +18,12 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
import * as classNames from 'classnames';
import DocMarkdownBlock from './DocMarkdownBlock';
import HelpIcon from '../icons-components/HelpIcon';
import Tooltip from '../controls/Tooltip';
import OutsideClickHandler from '../controls/OutsideClickHandler';
import * as theme from '../../app/theme';
import HelpTooltip from '../controls/HelpTooltip';

interface Props {
className?: string;
children?: React.ReactNode;
/** Key of the documentation chunk */
doc: string;
}
@@ -77,23 +74,6 @@ export default class DocTooltip extends React.PureComponent<Props, State> {
this.setState({ open: false });
};

handleHelpClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault();
event.currentTarget.blur();
if (!this.state.open && !this.state.loading && this.state.content === undefined) {
this.fetchContent();
}

if (this.state.open) {
this.setState({ open: false });
} else {
// defer opening to not trigger OutsideClickHandler.onClickOutside callback
setTimeout(() => {
this.setState({ open: true });
}, 0);
}
};

renderOverlay() {
if (this.state.loading) {
return (
@@ -103,32 +83,17 @@ export default class DocTooltip extends React.PureComponent<Props, State> {
);
}

return (
<OutsideClickHandler onClickOutside={this.close}>
{({ ref }) => (
<div ref={ref}>
<DocMarkdownBlock className="cut-margins abs-width-300" content={this.state.content} />
</div>
)}
</OutsideClickHandler>
);
return <DocMarkdownBlock className="cut-margins abs-width-300" content={this.state.content} />;
}

render() {
return (
<div className={classNames('display-flex-center', this.props.className)}>
<Tooltip
classNameSpace="popup"
overlay={this.renderOverlay()}
visible={this.state.content !== undefined && this.state.open}>
<a
className="display-flex-center link-no-underline"
href="#"
onClick={this.handleHelpClick}>
<HelpIcon fill={theme.gray80} size={12} />
</a>
</Tooltip>
</div>
<HelpTooltip
className={this.props.className}
onShow={this.fetchContent}
overlay={this.renderOverlay()}>
{this.props.children}
</HelpTooltip>
);
}
}

+ 0
- 9
server/sonar-web/src/main/js/components/docs/__tests__/DocTooltip-test.tsx Переглянути файл

@@ -20,7 +20,6 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import DocTooltip from '../DocTooltip';
import { click } from '../../../helpers/testUtils';

jest.useFakeTimers();

@@ -38,11 +37,3 @@ it('should reset state when receiving new doc', () => {
wrapper.setProps({ doc: 'baz' });
expect(wrapper.state()).toEqual({ content: undefined, loading: false, open: false });
});

it('should toggle', () => {
const wrapper = shallow(<DocTooltip doc="foo/bar" />);
expect(wrapper.state('open')).toBe(false);
click(wrapper.find('a'));
jest.runAllTimers();
expect(wrapper.state('open')).toBe(true);
});

+ 12
- 3
server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocLink-test.tsx.snap Переглянути файл

@@ -1,7 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render simple link 1`] = `
<a
href="http://sample.com"
/>
<React.Fragment>
<a
className="text-middle"
href="http://sample.com"
rel="noopener noreferrer"
target="_blank"
/>
<DetachIcon
className="text-middle text-muted little-spacer-left little-spacer-right"
size={12}
/>
</React.Fragment>
`;

+ 19
- 52
server/sonar-web/src/main/js/components/docs/__tests__/__snapshots__/DocTooltip-test.tsx.snap Переглянути файл

@@ -1,61 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`should render 1`] = `
<div
className="display-flex-center"
>
<Tooltip
classNameSpace="popup"
overlay={
<div
className="abs-width-300"
>
<i
className="spinner"
/>
</div>
}
visible={true}
>
<a
className="display-flex-center link-no-underline"
href="#"
onClick={[Function]}
<HelpTooltip
onShow={[Function]}
overlay={
<div
className="abs-width-300"
>
<HelpIcon
fill="#cdcdcd"
size={12}
<i
className="spinner"
/>
</a>
</Tooltip>
</div>
</div>
}
/>
`;

exports[`should render 2`] = `
<div
className="display-flex-center"
>
<Tooltip
classNameSpace="popup"
overlay={
<OutsideClickHandler
onClickOutside={[Function]}
>
[Function]
</OutsideClickHandler>
}
visible={true}
>
<a
className="display-flex-center link-no-underline"
href="#"
onClick={[Function]}
>
<HelpIcon
fill="#cdcdcd"
size={12}
/>
</a>
</Tooltip>
</div>
<HelpTooltip
onShow={[Function]}
overlay={
<DocMarkdownBlock
className="cut-margins abs-width-300"
content="this is *bold* text"
/>
}
/>
`;

+ 4
- 11
server/sonar-web/src/main/js/components/facet/FacetHeader.tsx Переглянути файл

@@ -19,8 +19,7 @@
*/
import * as React from 'react';
import OpenCloseIcon from '../icons-components/OpenCloseIcon';
import HelpIcon from '../icons-components/HelpIcon';
import Tooltip from '../controls/Tooltip';
import HelpTooltip from '../controls/HelpTooltip';
import { Button } from '../ui/buttons';
import { translate, translateWithParameters } from '../../helpers/l10n';

@@ -47,13 +46,7 @@ export default class FacetHeader extends React.PureComponent<Props> {
if (!this.props.helper) {
return null;
}
return (
<Tooltip overlay={this.props.helper}>
<span>
<HelpIcon className="spacer-left text-info" />
</span>
</Tooltip>
);
return <HelpTooltip className="spacer-left" overlay={this.props.helper} />;
}

renderValueIndicator() {
@@ -77,7 +70,7 @@ export default class FacetHeader extends React.PureComponent<Props> {
return (
<div className="search-navigator-facet-header-wrapper">
{this.props.onClick ? (
<span className="search-navigator-facet-header">
<span className="search-navigator-facet-header display-flex-center">
<a href="#" onClick={this.handleClick}>
<OpenCloseIcon className="little-spacer-right" open={this.props.open} />
{this.props.name}
@@ -85,7 +78,7 @@ export default class FacetHeader extends React.PureComponent<Props> {
{this.renderHelper()}
</span>
) : (
<span className="search-navigator-facet-header">
<span className="search-navigator-facet-header display-flex-center">
{this.props.name}
{this.renderHelper()}
</span>

+ 6
- 6
server/sonar-web/src/main/js/components/facet/__tests__/__snapshots__/FacetHeader-test.tsx.snap Переглянути файл

@@ -5,7 +5,7 @@ exports[`should clear 1`] = `
className="search-navigator-facet-header-wrapper"
>
<span
className="search-navigator-facet-header"
className="search-navigator-facet-header display-flex-center"
>
<a
href="#"
@@ -42,7 +42,7 @@ exports[`should render closed facet with value 1`] = `
className="search-navigator-facet-header-wrapper"
>
<span
className="search-navigator-facet-header"
className="search-navigator-facet-header display-flex-center"
>
<a
href="#"
@@ -73,7 +73,7 @@ exports[`should render closed facet without value 1`] = `
className="search-navigator-facet-header-wrapper"
>
<span
className="search-navigator-facet-header"
className="search-navigator-facet-header display-flex-center"
>
<a
href="#"
@@ -97,7 +97,7 @@ exports[`should render open facet with value 1`] = `
className="search-navigator-facet-header-wrapper"
>
<span
className="search-navigator-facet-header"
className="search-navigator-facet-header display-flex-center"
>
<a
href="#"
@@ -121,7 +121,7 @@ exports[`should render open facet without value 1`] = `
className="search-navigator-facet-header-wrapper"
>
<span
className="search-navigator-facet-header"
className="search-navigator-facet-header display-flex-center"
>
<a
href="#"
@@ -145,7 +145,7 @@ exports[`should render without link 1`] = `
className="search-navigator-facet-header-wrapper"
>
<span
className="search-navigator-facet-header"
className="search-navigator-facet-header display-flex-center"
>
foo
</span>

+ 5
- 5
server/sonar-web/src/main/js/components/icons-components/HelpIcon.tsx Переглянути файл

@@ -24,16 +24,16 @@ export default function HelpIcon({ className, fill = 'currentColor', size = 16 }
return (
<svg
className={className}
width={size}
height={size}
viewBox="0 0 16 16"
version="1.1"
xmlnsXlink="http://www.w3.org/1999/xlink"
xmlSpace="preserve">
viewBox="0 0 16 16"
width={size}
xmlSpace="preserve"
xmlnsXlink="http://www.w3.org/1999/xlink">
<g transform="matrix(0.0364583,0,0,0.0364583,1,-0.166667)">
<path
style={{ fill }}
d="M224,344L224,296C224,293.667 223.25,291.75 221.75,290.25C220.25,288.75 218.333,288 216,288L168,288C165.667,288 163.75,288.75 162.25,290.25C160.75,291.75 160,293.667 160,296L160,344C160,346.333 160.75,348.25 162.25,349.75C163.75,351.25 165.667,352 168,352L216,352C218.333,352 220.25,351.25 221.75,349.75C223.25,348.25 224,346.333 224,344ZM288,176C288,161.333 283.375,147.75 274.125,135.25C264.875,122.75 253.333,113.083 239.5,106.25C225.667,99.417 211.5,96 197,96C156.5,96 125.583,113.75 104.25,149.25C101.75,153.25 102.417,156.75 106.25,159.75L139.25,184.75C140.417,185.75 142,186.25 144,186.25C146.667,186.25 148.75,185.25 150.25,183.25C159.083,171.917 166.25,164.25 171.75,160.25C177.417,156.25 184.583,154.25 193.25,154.25C201.25,154.25 208.375,156.417 214.625,160.75C220.875,165.083 224,170 224,175.5C224,181.833 222.333,186.917 219,190.75C215.667,194.583 210,198.333 202,202C191.5,206.667 181.875,213.875 173.125,223.625C164.375,233.375 160,243.833 160,255L160,264C160,266.333 160.75,268.25 162.25,269.75C163.75,271.25 165.667,272 168,272L216,272C218.333,272 220.25,271.25 221.75,269.75C223.25,268.25 224,266.333 224,264C224,260.833 225.792,256.708 229.375,251.625C232.958,246.542 237.5,242.417 243,239.25C248.333,236.25 252.417,233.875 255.25,232.125C258.083,230.375 261.917,227.458 266.75,223.375C271.583,219.292 275.292,215.292 277.875,211.375C280.458,207.458 282.792,202.417 284.875,196.25C286.958,190.083 288,183.333 288,176ZM384,224C384,258.833 375.417,290.958 358.25,320.375C341.083,349.792 317.792,373.083 288.375,390.25C258.958,407.417 226.833,416 192,416C157.167,416 125.042,407.417 95.625,390.25C66.208,373.083 42.917,349.792 25.75,320.375C8.583,290.958 0,258.833 0,224C0,189.167 8.583,157.042 25.75,127.625C42.917,98.208 66.208,74.917 95.625,57.75C125.042,40.583 157.167,32 192,32C226.833,32 258.958,40.583 288.375,57.75C317.792,74.917 341.083,98.208 358.25,127.625C375.417,157.042 384,189.167 384,224Z"
style={{ fill }}
/>
</g>
</svg>

+ 3
- 7
sonar-core/src/main/resources/org/sonar/l10n/core.properties Переглянути файл

@@ -2559,11 +2559,11 @@ organization.change_visibility_form.submit=Change Default Visibility
#
#------------------------------------------------------------------------------
embed_docs.suggestion=Suggestions For This Page
embed_docs.documentation_index=Documentation index
embed_docs.documentation=Documentation
embed_docs.get_support=Get Support
embed_docs.stay_connected=Stay Connected
embed_docs.contact_form=Contact form
embed_docs.analyze_new_project=Analyze new project
embed_docs.contact_form=Contact Form
embed_docs.analyze_new_project=Analyze New Project

#------------------------------------------------------------------------------
#
@@ -2679,8 +2679,6 @@ onboarding.project_watcher.failed=Something went wrong, please check the analysi
# BRANCHES
#
#------------------------------------------------------------------------------
branches.learn_how_to_analyze=Learn how to analyze branches in SonarQube
branches.learn_how_to_analyze.text=Quickly setup branch analysis and get separate insights for each of your branches and pull requests.
branches.delete=Delete Branch
branches.delete.are_you_sure=Are you sure you want to delete branch "{0}"?
branches.pull_request.delete=Delete Pull Request
@@ -2697,8 +2695,6 @@ branches.detection_of_long_living_branches=Detection of long living branches
branches.detection_of_long_living_branches.description=Regular expression used to detect whether a branch is a long living branch (as opposed to short living branch), based on its name. This applies only during first analysis, the type of a branch cannot be changed later.
branches.set_leak_period=Set Leak Period
branches.last_analysis_date=Last Analysis Date
branches.no_support.header=Get the most out of SonarQube with branches analysis
branches.no_support.header.text=Analyze each branch of your project separately with the Developer Edition.
branches.search_for_branches=Search for branches...
branches.pull_requests=Pull Requests
branches.short_lived.quality_gate.description=The branch status is passed because there are no open issue. The remaining {0} issue(s) have been confirmed.

Завантаження…
Відмінити
Зберегти