**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) |
**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) |
public QualityProfilePage shouldHaveMissingSonarWayRules(Integer nbRules) { | public QualityProfilePage shouldHaveMissingSonarWayRules(Integer nbRules) { | ||||
Selenide.$(".quality-profile-rules-sonarway-missing") | Selenide.$(".quality-profile-rules-sonarway-missing") | ||||
.shouldBe(Condition.visible) | .shouldBe(Condition.visible) | ||||
.$("a").shouldHave(Condition.text(nbRules.toString())); | |||||
.shouldHave(Condition.text(nbRules.toString())); | |||||
return this; | return this; | ||||
} | } | ||||
public RulesPage showMissingSonarWayRules() { | public RulesPage showMissingSonarWayRules() { | ||||
Selenide.$(".quality-profile-rules-sonarway-missing") | Selenide.$(".quality-profile-rules-sonarway-missing") | ||||
.shouldBe(Condition.visible).$("a").click(); | |||||
.shouldBe(Condition.visible).$("[data-test=\"rules\"]").click(); | |||||
return Selenide.page(RulesPage.class); | return Selenide.page(RulesPage.class); | ||||
} | } | ||||
import * as PropTypes from 'prop-types'; | import * as PropTypes from 'prop-types'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import { SuggestionLink } from './SuggestionsProvider'; | import { SuggestionLink } from './SuggestionsProvider'; | ||||
import { CurrentUser, isLoggedIn } from '../../types'; | |||||
import BubblePopup, { BubblePopupPosition } from '../../../components/common/BubblePopup'; | import BubblePopup, { BubblePopupPosition } from '../../../components/common/BubblePopup'; | ||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
import { getBaseUrl } from '../../../helpers/urls'; | import { getBaseUrl } from '../../../helpers/urls'; | ||||
interface Props { | interface Props { | ||||
currentUser: CurrentUser; | |||||
onClose: () => void; | onClose: () => void; | ||||
popupPosition?: BubblePopupPosition; | popupPosition?: BubblePopupPosition; | ||||
suggestions: Array<SuggestionLink>; | suggestions: Array<SuggestionLink>; | ||||
translate('embed_docs.contact_form') | translate('embed_docs.contact_form') | ||||
)} | )} | ||||
</li> | </li> | ||||
<li className="divider" /> | |||||
{this.renderTitle(translate('embed_docs.stay_connected'))} | {this.renderTitle(translate('embed_docs.stay_connected'))} | ||||
<li> | <li> | ||||
{this.renderIconLink('https://about.sonarcloud.io/news/', 'sc-icon.svg', 'Product News')} | {this.renderIconLink('https://about.sonarcloud.io/news/', 'sc-icon.svg', 'Product News')} | ||||
renderSonarQubeLinks() { | renderSonarQubeLinks() { | ||||
return ( | return ( | ||||
<React.Fragment> | <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" /> | <li className="divider" /> | ||||
{this.renderTitle(translate('embed_docs.get_support'))} | {this.renderTitle(translate('embed_docs.get_support'))} | ||||
<li> | <li> | ||||
'Stack Overflow' | 'Stack Overflow' | ||||
)} | )} | ||||
</li> | </li> | ||||
<li className="divider" /> | |||||
{this.renderTitle(translate('embed_docs.stay_connected'))} | {this.renderTitle(translate('embed_docs.stay_connected'))} | ||||
<li> | <li> | ||||
{this.renderIconLink('https://blog.sonarsource.com/', 'sq-icon.svg', 'Product News')} | {this.renderIconLink('https://blog.sonarsource.com/', 'sq-icon.svg', 'Product News')} | ||||
{this.renderSuggestions()} | {this.renderSuggestions()} | ||||
<li> | <li> | ||||
<Link onClick={this.props.onClose} to="/documentation"> | <Link onClick={this.props.onClose} to="/documentation"> | ||||
{translate('embed_docs.documentation_index')} | |||||
{translate('embed_docs.documentation')} | |||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<li> | <li> |
import * as React from 'react'; | import * as React from 'react'; | ||||
import EmbedDocsPopup from './EmbedDocsPopup'; | import EmbedDocsPopup from './EmbedDocsPopup'; | ||||
import { SuggestionLink } from './SuggestionsProvider'; | import { SuggestionLink } from './SuggestionsProvider'; | ||||
import { CurrentUser } from '../../types'; | |||||
import BubblePopupHelper from '../../../components/common/BubblePopupHelper'; | import BubblePopupHelper from '../../../components/common/BubblePopupHelper'; | ||||
import HelpIcon from '../../../components/icons-components/HelpIcon'; | import HelpIcon from '../../../components/icons-components/HelpIcon'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | import Tooltip from '../../../components/controls/Tooltip'; | ||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
interface Props { | interface Props { | ||||
currentUser: CurrentUser; | |||||
showTooltip: boolean; | showTooltip: boolean; | ||||
suggestions: Array<SuggestionLink>; | suggestions: Array<SuggestionLink>; | ||||
tooltip: boolean; | tooltip: boolean; | ||||
<BubblePopupHelper | <BubblePopupHelper | ||||
isOpen={this.state.helpOpen} | isOpen={this.state.helpOpen} | ||||
offset={{ horizontal: 12, vertical: -10 }} | 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" | position="bottomleft" | ||||
togglePopup={this.setHelpDisplay}> | togglePopup={this.setHelpDisplay}> | ||||
<Tooltip | <Tooltip |
it('should display suggestion links', () => { | it('should display suggestion links', () => { | ||||
const context = {}; | 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(); | wrapper.update(); | ||||
expect(wrapper).toMatchSnapshot(); | expect(wrapper).toMatchSnapshot(); | ||||
}); | }); |
style={Object {}} | style={Object {}} | ||||
to="/documentation" | to="/documentation" | ||||
> | > | ||||
embed_docs.documentation_index | |||||
embed_docs.documentation | |||||
</Link> | </Link> | ||||
</li> | </li> | ||||
<li> | <li> | ||||
Stack Overflow | Stack Overflow | ||||
</a> | </a> | ||||
</li> | </li> | ||||
<li | |||||
className="divider" | |||||
/> | |||||
<li | <li | ||||
className="dropdown-header" | className="dropdown-header" | ||||
> | > |
import * as PropTypes from 'prop-types'; | import * as PropTypes from 'prop-types'; | ||||
import { FormattedMessage } from 'react-intl'; | import { FormattedMessage } from 'react-intl'; | ||||
import ComponentNavBranchesMenu from './ComponentNavBranchesMenu'; | import ComponentNavBranchesMenu from './ComponentNavBranchesMenu'; | ||||
import SingleBranchHelperPopup from './SingleBranchHelperPopup'; | |||||
import NoBranchSupportPopup from './NoBranchSupportPopup'; | |||||
import DocTooltip from '../../../../components/docs/DocTooltip'; | |||||
import { BranchLike, Component } from '../../../types'; | import { BranchLike, Component } from '../../../types'; | ||||
import * as theme from '../../../theme'; | import * as theme from '../../../theme'; | ||||
import BranchIcon from '../../../../components/icons-components/BranchIcon'; | import BranchIcon from '../../../../components/icons-components/BranchIcon'; | ||||
} from '../../../../helpers/branches'; | } from '../../../../helpers/branches'; | ||||
import { translate } from '../../../../helpers/l10n'; | import { translate } from '../../../../helpers/l10n'; | ||||
import PlusCircleIcon from '../../../../components/icons-components/PlusCircleIcon'; | 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'; | import Tooltip from '../../../../components/controls/Tooltip'; | ||||
interface Props { | interface Props { | ||||
if (isShortLivingBranch(currentBranchLike)) { | if (isShortLivingBranch(currentBranchLike)) { | ||||
return currentBranchLike.isOrphan ? ( | return currentBranchLike.isOrphan ? ( | ||||
<span className="note big-spacer-left text-ellipsis flex-shrink"> | <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> | ||||
) : ( | ) : ( | ||||
<span className="note big-spacer-left"> | <span className="note big-spacer-left"> | ||||
} | } | ||||
}; | }; | ||||
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() { | render() { | ||||
const { branchLikes, currentBranchLike } = this.props; | const { branchLikes, currentBranchLike } = this.props; | ||||
fill={theme.gray80} | fill={theme.gray80} | ||||
/> | /> | ||||
<span className="note">{displayName}</span> | <span className="note">{displayName}</span> | ||||
{this.renderNoBranchSupportPopup()} | |||||
<DocTooltip className="spacer-left" doc="branches/no-branch-support"> | |||||
<PlusCircleIcon fill={theme.gray71} size={12} /> | |||||
</DocTooltip> | |||||
</div> | </div> | ||||
); | ); | ||||
} | } | ||||
<div className="navbar-context-branches"> | <div className="navbar-context-branches"> | ||||
<BranchIcon branchLike={currentBranchLike} className="little-spacer-right" /> | <BranchIcon branchLike={currentBranchLike} className="little-spacer-right" /> | ||||
<span className="note">{displayName}</span> | <span className="note">{displayName}</span> | ||||
{this.renderSingleBranchPopup()} | |||||
<DocTooltip className="spacer-left" doc="branches/single-branch"> | |||||
<PlusCircleIcon fill={theme.blue} size={12} /> | |||||
</DocTooltip> | |||||
</div> | </div> | ||||
); | ); | ||||
} | } |
import { translate } from '../../../../helpers/l10n'; | import { translate } from '../../../../helpers/l10n'; | ||||
import { getBranchLikeUrl } from '../../../../helpers/urls'; | import { getBranchLikeUrl } from '../../../../helpers/urls'; | ||||
import SearchBox from '../../../../components/controls/SearchBox'; | import SearchBox from '../../../../components/controls/SearchBox'; | ||||
import Tooltip from '../../../../components/controls/Tooltip'; | |||||
import HelpTooltip from '../../../../components/controls/HelpTooltip'; | |||||
interface Props { | interface Props { | ||||
branchLikes: BranchLike[]; | branchLikes: BranchLike[]; | ||||
{showDivider && <li className="divider" />} | {showDivider && <li className="divider" />} | ||||
{showOrphanHeader && ( | {showOrphanHeader && ( | ||||
<li className="dropdown-header"> | <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> | </li> | ||||
)} | )} | ||||
{showPullRequestHeader && ( | {showPullRequestHeader && ( |
/* | |||||
* 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> | |||||
</> | |||||
); | |||||
} |
/>, | />, | ||||
{ context: { branchesEnabled: true } } | { context: { branchesEnabled: true } } | ||||
); | ); | ||||
expect(wrapper.find('Popup')).toMatchSnapshot(); | |||||
expect(wrapper.find('DocTooltip')).toMatchSnapshot(); | |||||
}); | }); | ||||
it('renders no branch support popup', () => { | it('renders no branch support popup', () => { | ||||
/>, | />, | ||||
{ context: { branchesEnabled: false } } | { context: { branchesEnabled: false } } | ||||
); | ); | ||||
expect(wrapper.find('Popup')).toMatchSnapshot(); | |||||
expect(wrapper.find('DocTooltip')).toMatchSnapshot(); | |||||
}); | }); | ||||
it('renders nothing on SonarCloud without branch support', () => { | it('renders nothing on SonarCloud without branch support', () => { |
`; | `; | ||||
exports[`renders no branch support popup 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`] = ` | exports[`renders pull request 1`] = ` | ||||
`; | `; | ||||
exports[`renders single branch popup 1`] = ` | exports[`renders single branch popup 1`] = ` | ||||
<Popup | |||||
overlay={<SingleBranchHelperPopup />} | |||||
/> | |||||
<DocTooltip | |||||
className="spacer-left" | |||||
doc="branches/single-branch" | |||||
> | |||||
<PlusCircleIcon | |||||
fill="#4b9fd5" | |||||
size={12} | |||||
/> | |||||
</DocTooltip> | |||||
`; | `; |
<li | <li | ||||
className="dropdown-header" | 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> | </li> | ||||
<ComponentNavBranchesMenuItem | <ComponentNavBranchesMenuItem | ||||
branchLike={ | branchLike={ | ||||
<li | <li | ||||
className="dropdown-header" | 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> | </li> | ||||
<ComponentNavBranchesMenuItem | <ComponentNavBranchesMenuItem | ||||
branchLike={ | branchLike={ |
// 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> | |||||
`; |
// 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> | |||||
`; |
<GlobalNavExplore location={this.props.location} onSonarCloud={this.props.onSonarCloud} /> | <GlobalNavExplore location={this.props.location} onSonarCloud={this.props.onSonarCloud} /> | ||||
<li> | <li> | ||||
<EmbedDocsPopupHelper | <EmbedDocsPopupHelper | ||||
currentUser={this.props.currentUser} | |||||
showTooltip={this.state.onboardingTutorialTooltip} | showTooltip={this.state.onboardingTutorialTooltip} | ||||
suggestions={this.props.suggestions} | suggestions={this.props.suggestions} | ||||
tooltip={!this.props.onSonarCloud} | tooltip={!this.props.onSonarCloud} |
} | } | ||||
} | } | ||||
.icon-help:before { | |||||
content: '\f059'; | |||||
color: var(--blue); | |||||
font-size: var(--bigFontSize); | |||||
} | |||||
.icon-close:before { | .icon-close:before { | ||||
content: '\f00d'; | content: '\f00d'; | ||||
font-size: var(--bigFontSize); | font-size: var(--bigFontSize); |
import HomePageSelect from '../../components/controls/HomePageSelect'; | import HomePageSelect from '../../components/controls/HomePageSelect'; | ||||
import ListFooter from '../../components/controls/ListFooter'; | import ListFooter from '../../components/controls/ListFooter'; | ||||
import Modal from '../../components/controls/Modal'; | import Modal from '../../components/controls/Modal'; | ||||
import HelpTooltip from '../../components/controls/HelpTooltip'; | |||||
import SearchBox from '../../components/controls/SearchBox'; | import SearchBox from '../../components/controls/SearchBox'; | ||||
import Select from '../../components/controls/Select'; | import Select from '../../components/controls/Select'; | ||||
import Tooltip from '../../components/controls/Tooltip'; | import Tooltip from '../../components/controls/Tooltip'; | ||||
DuplicationsRating, | DuplicationsRating, | ||||
EditButton, | EditButton, | ||||
FavoriteContainer, | FavoriteContainer, | ||||
HelpTooltip, | |||||
HomePageSelect, | HomePageSelect, | ||||
Level, | Level, | ||||
LicenseEditionSet, | LicenseEditionSet, |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import BubblePopup from '../../../components/common/BubblePopup'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
interface Props { | |||||
popupPosition?: any; | |||||
} | |||||
export default function NoWorkersSupportPopup(props: Props) { | |||||
export default function NoWorkersSupportPopup() { | |||||
return ( | 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> | |||||
</> | |||||
); | ); | ||||
} | } |
import WorkersForm from './WorkersForm'; | import WorkersForm from './WorkersForm'; | ||||
import NoWorkersSupportPopup from './NoWorkersSupportPopup'; | import NoWorkersSupportPopup from './NoWorkersSupportPopup'; | ||||
import AlertWarnIcon from '../../../components/icons-components/AlertWarnIcon'; | 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 Tooltip from '../../../components/controls/Tooltip'; | ||||
import * as theme from '../../../app/theme'; | |||||
import { getWorkers } from '../../../api/ce'; | import { getWorkers } from '../../../api/ce'; | ||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
import { EditButton } from '../../../components/ui/buttons'; | import { EditButton } from '../../../components/ui/buttons'; | ||||
const { canSetWorkerCount, formOpen, loading, workerCount } = this.state; | const { canSetWorkerCount, formOpen, loading, workerCount } = this.state; | ||||
return ( | return ( | ||||
<div> | |||||
<div className="display-flex-center"> | |||||
{!loading && | {!loading && | ||||
workerCount > 1 && ( | workerCount > 1 && ( | ||||
<Tooltip overlay={translate('background_tasks.number_of_workers.warning')}> | <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> | </span> | ||||
</Tooltip> | </Tooltip> | ||||
)} | )} | ||||
{!loading && | {!loading && | ||||
!canSetWorkerCount && ( | !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} />} | {formOpen && <WorkersForm onClose={this.closeForm} workerCount={this.state.workerCount} />} |
// Jest Snapshot v1, https://goo.gl/fbAQLP | // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
exports[`opens form 1`] = ` | exports[`opens form 1`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<span | <span | ||||
className="text-middle" | className="text-middle" | ||||
> | > | ||||
`; | `; | ||||
exports[`opens form 2`] = ` | exports[`opens form 2`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<span | <span | ||||
className="text-middle" | className="text-middle" | ||||
> | > | ||||
`; | `; | ||||
exports[`renders 1`] = ` | exports[`renders 1`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<span | <span | ||||
className="text-middle" | className="text-middle" | ||||
> | > | ||||
`; | `; | ||||
exports[`renders 2`] = ` | exports[`renders 2`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<span | <span | ||||
className="text-middle" | className="text-middle" | ||||
> | > | ||||
`; | `; | ||||
exports[`renders 3`] = ` | exports[`renders 3`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<Tooltip | <Tooltip | ||||
overlay="background_tasks.number_of_workers.warning" | overlay="background_tasks.number_of_workers.warning" | ||||
> | > | ||||
<span> | |||||
<span | |||||
className="display-inline-flex-center little-spacer-right" | |||||
> | |||||
<AlertWarnIcon | <AlertWarnIcon | ||||
className="little-spacer-right bt-workers-warning-icon" | |||||
fill="#d3d3d3" | fill="#d3d3d3" | ||||
/> | /> | ||||
</span> | </span> | ||||
`; | `; | ||||
exports[`renders 4`] = ` | exports[`renders 4`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<Tooltip | <Tooltip | ||||
overlay="background_tasks.number_of_workers.warning" | overlay="background_tasks.number_of_workers.warning" | ||||
> | > | ||||
<span> | |||||
<span | |||||
className="display-inline-flex-center little-spacer-right" | |||||
> | |||||
<AlertWarnIcon | <AlertWarnIcon | ||||
className="little-spacer-right bt-workers-warning-icon" | |||||
fill="#d3d3d3" | fill="#d3d3d3" | ||||
/> | /> | ||||
</span> | </span> | ||||
2 | 2 | ||||
</strong> | </strong> | ||||
</span> | </span> | ||||
<span | |||||
<HelpTooltip | |||||
className="spacer-left" | 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> | </div> | ||||
`; | `; | ||||
exports[`updates worker count 1`] = ` | exports[`updates worker count 1`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<span | <span | ||||
className="text-middle" | className="text-middle" | ||||
> | > | ||||
`; | `; | ||||
exports[`updates worker count 2`] = ` | exports[`updates worker count 2`] = ` | ||||
<div> | |||||
<div | |||||
className="display-flex-center" | |||||
> | |||||
<Tooltip | <Tooltip | ||||
overlay="background_tasks.number_of_workers.warning" | overlay="background_tasks.number_of_workers.warning" | ||||
> | > | ||||
<span> | |||||
<span | |||||
className="display-inline-flex-center little-spacer-right" | |||||
> | |||||
<AlertWarnIcon | <AlertWarnIcon | ||||
className="little-spacer-right bt-workers-warning-icon" | |||||
fill="#d3d3d3" | fill="#d3d3d3" | ||||
/> | /> | ||||
</span> | </span> |
import EmptyResult from './EmptyResult'; | import EmptyResult from './EmptyResult'; | ||||
import OriginalBubbleChart from '../../../components/charts/BubbleChart'; | import OriginalBubbleChart from '../../../components/charts/BubbleChart'; | ||||
import ColorRatingsLegend from '../../../components/charts/ColorRatingsLegend'; | 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 { formatMeasure, isDiffMetric } from '../../../helpers/measures'; | ||||
import { | import { | ||||
getLocalizedMetricDomain, | getLocalizedMetricDomain, | ||||
return ( | return ( | ||||
<div className="measure-overview-bubble-chart-header"> | <div className="measure-overview-bubble-chart-header"> | ||||
<span className="measure-overview-bubble-chart-title"> | <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> | ||||
<span className="measure-overview-bubble-chart-legend"> | <span className="measure-overview-bubble-chart-legend"> | ||||
<span className="note"> | <span className="note"> |
import DocMarkdownBlock from '../../../components/docs/DocMarkdownBlock'; | import DocMarkdownBlock from '../../../components/docs/DocMarkdownBlock'; | ||||
import DeferredSpinner from '../../../components/common/DeferredSpinner'; | import DeferredSpinner from '../../../components/common/DeferredSpinner'; | ||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
import '../styles.css'; | |||||
interface Props { | interface Props { | ||||
params: { splat?: string }; | params: { splat?: string }; | ||||
return ( | return ( | ||||
<div className="boxed-group"> | <div className="boxed-group"> | ||||
<DocMarkdownBlock | <DocMarkdownBlock | ||||
className="cut-margins boxed-group-inner" | |||||
className="documentation-content cut-margins boxed-group-inner" | |||||
content={this.state.content} | content={this.state.content} | ||||
displayH1={true} | displayH1={true} | ||||
/> | /> | ||||
</ScreenPositionHelper> | </ScreenPositionHelper> | ||||
<div className="layout-page-main"> | <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> | ||||
</div> | </div> | ||||
); | ); |
* along with this program; if not, write to the Free Software Foundation, | * along with this program; if not, write to the Free Software Foundation, | ||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * 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; | |||||
} |
import Checkbox from '../../../components/controls/Checkbox'; | import Checkbox from '../../../components/controls/Checkbox'; | ||||
import Modal from '../../../components/controls/Modal'; | import Modal from '../../../components/controls/Modal'; | ||||
import Select from '../../../components/controls/Select'; | 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 SeverityHelper from '../../../components/shared/SeverityHelper'; | ||||
import Avatar from '../../../components/ui/Avatar'; | import Avatar from '../../../components/ui/Avatar'; | ||||
import { SubmitButton } from '../../../components/ui/buttons'; | import { SubmitButton } from '../../../components/ui/buttons'; | ||||
return ( | return ( | ||||
<div className="modal-field"> | <div className="modal-field"> | ||||
<label htmlFor="comment"> | <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> | </label> | ||||
<div> | <div> | ||||
<textarea | <textarea |
import React from 'react'; | import React from 'react'; | ||||
import QualityGateConditions from './QualityGateConditions'; | import QualityGateConditions from './QualityGateConditions'; | ||||
import EmptyQualityGate from './EmptyQualityGate'; | import EmptyQualityGate from './EmptyQualityGate'; | ||||
import * as theme from '../../../app/theme'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
import Level from '../../../components/ui/Level'; | 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 DocTooltip from '../../../components/docs/DocTooltip'; | ||||
import HelpIcon from '../../../components/icons-components/HelpIcon'; | |||||
/*:: import type { Component, MeasuresList } from '../types'; */ | /*:: import type { Component, MeasuresList } from '../types'; */ | ||||
function parseQualityGateDetails(rawDetails /*: string */) { | function parseQualityGateDetails(rawDetails /*: string */) { | ||||
{ignoredConditions && ( | {ignoredConditions && ( | ||||
<div className="alert alert-info display-inline-block big-spacer-top"> | <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> | </div> | ||||
)} | )} | ||||
<div | <div | ||||
className="alert alert-info display-inline-block big-spacer-top" | 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> | ||||
</div> | </div> | ||||
`; | `; |
*/ | */ | ||||
import React from 'react'; | import React from 'react'; | ||||
import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | |||||
import HelpTooltip from '../../../components/controls/HelpTooltip'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
export default class ListHeader extends React.PureComponent { | export default class ListHeader extends React.PureComponent { | ||||
render() { | render() { | ||||
const cells = this.props.permissions.map(permission => ( | 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> | </th> | ||||
)); | )); | ||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import HelpTooltip from '../../../../components/controls/HelpTooltip'; | |||||
import Tooltip from '../../../../components/controls/Tooltip'; | import Tooltip from '../../../../components/controls/Tooltip'; | ||||
import { translate, translateWithParameters } from '../../../../helpers/l10n'; | import { translate, translateWithParameters } from '../../../../helpers/l10n'; | ||||
'global_permissions.filter_by_x_permission', | 'global_permissions.filter_by_x_permission', | ||||
permission.name | permission.name | ||||
)}> | )}> | ||||
<a href="#" onClick={this.handlePermissionClick}> | |||||
<a className="text-middle" href="#" onClick={this.handlePermissionClick}> | |||||
{permission.name} | {permission.name} | ||||
</a> | </a> | ||||
</Tooltip> | </Tooltip> | ||||
<Tooltip overlay={this.renderTooltip(permission)}> | |||||
<i className="icon-help little-spacer-left" /> | |||||
</Tooltip> | |||||
<HelpTooltip className="spacer-left" overlay={this.renderTooltip(permission)} /> | |||||
</div> | </div> | ||||
</th> | </th> | ||||
); | ); |
} | } | ||||
.permissions-table .permission-column-inner { | .permissions-table .permission-column-inner { | ||||
width: 112px; | |||||
width: 100px; | |||||
} | } |
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
import { getValues } from '../../../api/settings'; | import { getValues } from '../../../api/settings'; | ||||
import { formatMeasure } from '../../../helpers/measures'; | import { formatMeasure } from '../../../helpers/measures'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | |||||
import HelpTooltip from '../../../components/controls/HelpTooltip'; | |||||
interface Props { | interface Props { | ||||
branchLikes: BranchLike[]; | branchLikes: BranchLike[]; | ||||
<React.Fragment key={getBranchLikeKey(branchLike)}> | <React.Fragment key={getBranchLikeKey(branchLike)}> | ||||
{showOrphanHeader && ( | {showOrphanHeader && ( | ||||
<li className="dropdown-header"> | <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> | </li> | ||||
)} | )} | ||||
<BranchRow | <BranchRow |
<li | <li | ||||
className="dropdown-header" | 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> | </li> | ||||
<BranchRow | <BranchRow | ||||
branchLike={ | branchLike={ |
import { translate, translateWithParameters } from '../../../helpers/l10n'; | import { translate, translateWithParameters } from '../../../helpers/l10n'; | ||||
import { RATING_COLORS } from '../../../helpers/constants'; | import { RATING_COLORS } from '../../../helpers/constants'; | ||||
import { getProjectUrl } from '../../../helpers/urls'; | 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 = 'sqale_index'; | ||||
const X_METRIC_TYPE = 'SHORT_WORK_DUR'; | const X_METRIC_TYPE = 'SHORT_WORK_DUR'; | ||||
</div> | </div> | ||||
<div className="measure-details-bubble-chart-axis size"> | <div className="measure-details-bubble-chart-axis size"> | ||||
<span className="measure-details-bubble-chart-title"> | <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> | </span> | ||||
<div> | <div> | ||||
<span className="spacer-right"> | <span className="spacer-right"> |
import { RATING_COLORS } from '../../../helpers/constants'; | import { RATING_COLORS } from '../../../helpers/constants'; | ||||
import { getProjectUrl } from '../../../helpers/urls'; | import { getProjectUrl } from '../../../helpers/urls'; | ||||
import { Project } from '../types'; | 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 { | export interface Metric { | ||||
key: string; | key: string; | ||||
</div> | </div> | ||||
<div className="measure-details-bubble-chart-axis size"> | <div className="measure-details-bubble-chart-axis size"> | ||||
<span className="measure-details-bubble-chart-title"> | <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> | </span> | ||||
<div> | <div> | ||||
{colorMetric != null && ( | {colorMetric != null && ( |
<span | <span | ||||
className="measure-details-bubble-chart-title" | 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> | </span> | ||||
<div> | <div> | ||||
<span | <span |
<span | <span | ||||
className="measure-details-bubble-chart-title" | className="measure-details-bubble-chart-title" | ||||
> | > | ||||
<Tooltip | |||||
<span | |||||
className="text-middle" | |||||
/> | |||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay="foobar" | overlay="foobar" | ||||
> | |||||
<span | |||||
className="spacer-left text-info" | |||||
> | |||||
<HelpIcon | |||||
className="text-bottom" | |||||
/> | |||||
</span> | |||||
</Tooltip> | |||||
/> | |||||
</span> | </span> | ||||
<div> | <div> | ||||
<span | <span |
import Checkbox from '../../components/controls/Checkbox'; | import Checkbox from '../../components/controls/Checkbox'; | ||||
import { translate } from '../../helpers/l10n'; | import { translate } from '../../helpers/l10n'; | ||||
import QualifierIcon from '../../components/shared/QualifierIcon'; | 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 DateInput from '../../components/controls/DateInput'; | ||||
import Select from '../../components/controls/Select'; | import Select from '../../components/controls/Select'; | ||||
import SearchBox from '../../components/controls/SearchBox'; | import SearchBox from '../../components/controls/SearchBox'; | ||||
className="link-checkbox-control" | className="link-checkbox-control" | ||||
id="projects-provisioned" | id="projects-provisioned" | ||||
onCheck={this.props.onProvisionedChanged}> | onCheck={this.props.onProvisionedChanged}> | ||||
<span className="little-spacer-left"> | |||||
<span className="text-middle little-spacer-left"> | |||||
{translate('provisioning.only_provisioned')} | {translate('provisioning.only_provisioned')} | ||||
<Tooltip overlay={translate('provisioning.only_provisioned.tooltip')}> | |||||
<i className="spacer-left icon-help" /> | |||||
</Tooltip> | |||||
</span> | </span> | ||||
</Checkbox> | </Checkbox> | ||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay={translate('provisioning.only_provisioned.tooltip')} | |||||
/> | |||||
</td> | </td> | ||||
) : null; | ) : null; | ||||
thirdState={false} | thirdState={false} | ||||
> | > | ||||
<span | <span | ||||
className="little-spacer-left" | |||||
className="text-middle little-spacer-left" | |||||
> | > | ||||
provisioning.only_provisioned | provisioning.only_provisioned | ||||
<Tooltip | |||||
overlay="provisioning.only_provisioned.tooltip" | |||||
> | |||||
<i | |||||
className="spacer-left icon-help" | |||||
/> | |||||
</Tooltip> | |||||
</span> | </span> | ||||
</Checkbox> | </Checkbox> | ||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay="provisioning.only_provisioned.tooltip" | |||||
/> | |||||
</td> | </td> | ||||
<td | <td | ||||
className="text-middle" | className="text-middle" | ||||
thirdState={false} | thirdState={false} | ||||
> | > | ||||
<span | <span | ||||
className="little-spacer-left" | |||||
className="text-middle little-spacer-left" | |||||
> | > | ||||
provisioning.only_provisioned | provisioning.only_provisioned | ||||
<Tooltip | |||||
overlay="provisioning.only_provisioned.tooltip" | |||||
> | |||||
<i | |||||
className="spacer-left icon-help" | |||||
/> | |||||
</Tooltip> | |||||
</span> | </span> | ||||
</Checkbox> | </Checkbox> | ||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay="provisioning.only_provisioned.tooltip" | |||||
/> | |||||
</td> | </td> | ||||
<td | <td | ||||
className="text-middle" | className="text-middle" |
import * as React from 'react'; | import * as React from 'react'; | ||||
import * as classNames from 'classnames'; | import * as classNames from 'classnames'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | import Tooltip from '../../../components/controls/Tooltip'; | ||||
import DocInclude from '../../../components/docs/DocInclude'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
interface Props { | interface Props { | ||||
className?: string; | className?: string; | ||||
tooltip?: boolean; | |||||
} | } | ||||
export default function BuiltInQualityGateBadge({ className, tooltip = true }: Props) { | |||||
export default function BuiltInQualityGateBadge({ className }: Props) { | |||||
const badge = ( | const badge = ( | ||||
<div className={classNames('outline-badge', className)}> | <div className={classNames('outline-badge', className)}> | ||||
{translate('quality_gates.built_in')} | {translate('quality_gates.built_in')} | ||||
); | ); | ||||
const overlay = ( | 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>; | |||||
} | } |
import CopyQualityGateForm from './CopyQualityGateForm'; | import CopyQualityGateForm from './CopyQualityGateForm'; | ||||
import DeleteQualityGateForm from './DeleteQualityGateForm'; | import DeleteQualityGateForm from './DeleteQualityGateForm'; | ||||
import { fetchQualityGate, QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates'; | import { fetchQualityGate, QualityGate, setQualityGateAsDefault } from '../../../api/quality-gates'; | ||||
import DocTooltip from '../../../components/docs/DocTooltip'; | |||||
import { Button } from '../../../components/ui/buttons'; | import { Button } from '../../../components/ui/buttons'; | ||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
<div className="layout-page-main-inner"> | <div className="layout-page-main-inner"> | ||||
<div className="pull-left display-flex-center"> | <div className="pull-left display-flex-center"> | ||||
<h2>{qualityGate.name}</h2> | <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> | ||||
<div className="pull-right"> | <div className="pull-right"> |
<td className="thin nowrap spacer-left text-right"> | <td className="thin nowrap spacer-left text-right"> | ||||
{qualityGate.isDefault && <span className="badge">{translate('default')}</span>} | {qualityGate.isDefault && <span className="badge">{translate('default')}</span>} | ||||
{qualityGate.isBuiltIn && ( | {qualityGate.isBuiltIn && ( | ||||
<BuiltInQualityGateBadge className="little-spacer-left" tooltip={false} /> | |||||
<BuiltInQualityGateBadge className="little-spacer-left" /> | |||||
)} | )} | ||||
</td> | </td> | ||||
</tr> | </tr> |
import * as React from 'react'; | import * as React from 'react'; | ||||
import * as classNames from 'classnames'; | import * as classNames from 'classnames'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | import Tooltip from '../../../components/controls/Tooltip'; | ||||
import DocInclude from '../../../components/docs/DocInclude'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
interface Props { | interface Props { | ||||
); | ); | ||||
const overlay = ( | 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>; | return <Tooltip overlay={tooltip ? overlay : undefined}>{badge}</Tooltip>; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import ProfileLink from '../components/ProfileLink'; | import ProfileLink from '../components/ProfileLink'; | ||||
import BuiltInQualityProfileBadge from '../components/BuiltInQualityProfileBadge'; | import BuiltInQualityProfileBadge from '../components/BuiltInQualityProfileBadge'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | |||||
import HelpTooltip from '../../../components/controls/HelpTooltip'; | |||||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | import { translate, translateWithParameters } from '../../../helpers/l10n'; | ||||
interface Props { | interface Props { | ||||
<div style={{ paddingLeft: offset }}> | <div style={{ paddingLeft: offset }}> | ||||
{displayLink ? ( | {displayLink ? ( | ||||
<ProfileLink | <ProfileLink | ||||
className="text-middle" | |||||
language={props.language} | language={props.language} | ||||
name={profile.name} | name={profile.name} | ||||
organization={props.organization}> | organization={props.organization}> | ||||
{profile.name} | {profile.name} | ||||
</ProfileLink> | </ProfileLink> | ||||
) : ( | ) : ( | ||||
profile.name | |||||
<span className="text-middle">{profile.name}</span> | |||||
)} | )} | ||||
{profile.isBuiltIn && <BuiltInQualityProfileBadge className="spacer-left" />} | {profile.isBuiltIn && <BuiltInQualityProfileBadge className="spacer-left" />} | ||||
{extendsBuiltIn && ( | {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> | </div> | ||||
</td> | </td> |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | |||||
import HelpTooltip from '../../../components/controls/HelpTooltip'; | |||||
import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls'; | import { getDeprecatedActiveRulesUrl } from '../../../helpers/urls'; | ||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
return ( | return ( | ||||
<div className="quality-profile-rules-deprecated clearfix"> | <div className="quality-profile-rules-deprecated clearfix"> | ||||
<span className="pull-left"> | <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> | </span> | ||||
<Link | <Link | ||||
className="pull-right" | className="pull-right" |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | |||||
import HelpTooltip from '../../../components/controls/HelpTooltip'; | |||||
import { getRulesUrl } from '../../../helpers/urls'; | import { getRulesUrl } from '../../../helpers/urls'; | ||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
return ( | return ( | ||||
<div className="quality-profile-rules-sonarway-missing clearfix"> | <div className="quality-profile-rules-sonarway-missing clearfix"> | ||||
<span className="pull-left"> | <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> | </span> | ||||
<Link className="pull-right" to={url}> | |||||
<Link className="pull-right" data-test="rules" to={url}> | |||||
{props.sonarWayMissingRules} | {props.sonarWayMissingRules} | ||||
</Link> | </Link> | ||||
</div> | </div> |
<span | <span | ||||
className="pull-left" | 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> | </span> | ||||
<Link | <Link | ||||
className="pull-right" | className="pull-right" |
<span | <span | ||||
className="pull-left" | 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> | </span> | ||||
<Link | <Link | ||||
className="pull-right" | className="pull-right" | ||||
data-test="rules" | |||||
onlyActiveOnIndex={false} | onlyActiveOnIndex={false} | ||||
style={Object {}} | style={Object {}} | ||||
to={ | to={ |
import { isStagnant } from '../utils'; | import { isStagnant } from '../utils'; | ||||
import { Profile } from '../types'; | import { Profile } from '../types'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | import Tooltip from '../../../components/controls/Tooltip'; | ||||
import DocTooltip from '../../../components/docs/DocTooltip'; | |||||
import DocInclude from '../../../components/docs/DocInclude'; | |||||
interface Props { | interface Props { | ||||
onRequestFail: (reason: any) => void; | onRequestFail: (reason: any) => void; | ||||
{profile.name} | {profile.name} | ||||
</ProfileLink> | </ProfileLink> | ||||
</div> | </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> | </div> | ||||
); | ); | ||||
} | } | ||||
if (profile.isDefault) { | if (profile.isDefault) { | ||||
return ( | return ( | ||||
<> | |||||
<Tooltip | |||||
overlay={ | |||||
<DocInclude | |||||
className="abs-width-300 cut-margins" | |||||
path="/tooltips/quality-profiles/default-quality-profile" | |||||
/> | |||||
}> | |||||
<span className="badge">{translate('default')}</span> | <span className="badge">{translate('default')}</span> | ||||
<DocTooltip className="table-cell-doc" doc="quality-profiles/default-quality-profile" /> | |||||
</> | |||||
</Tooltip> | |||||
); | ); | ||||
} | } | ||||
.oauth-providers-help { | .oauth-providers-help { | ||||
position: absolute; | position: absolute; | ||||
top: 12px; | |||||
right: -32px; | |||||
top: 15px; | |||||
right: -24px; | |||||
} | } | ||||
.oauth-providers + .login-form { | .oauth-providers + .login-form { |
import * as React from 'react'; | import * as React from 'react'; | ||||
import * as classNames from 'classnames'; | import * as classNames from 'classnames'; | ||||
import { translateWithParameters } from '../../../helpers/l10n'; | import { translateWithParameters } from '../../../helpers/l10n'; | ||||
import * as theme from '../../../app/theme'; | |||||
import { IdentityProvider } from '../../../app/types'; | 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 { isDarkColor } from '../../../helpers/colors'; | ||||
import { getBaseUrl } from '../../../helpers/urls'; | import { getBaseUrl } from '../../../helpers/urls'; | ||||
import './OAuthProviders.css'; | import './OAuthProviders.css'; | ||||
<span>{format(identityProvider.name)}</span> | <span>{format(identityProvider.name)}</span> | ||||
</a> | </a> | ||||
{identityProvider.helpMessage && ( | {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> | </li> | ||||
); | ); |
login.login_with_x.Bar | login.login_with_x.Bar | ||||
</span> | </span> | ||||
</a> | </a> | ||||
<Tooltip | |||||
<HelpTooltip | |||||
className="oauth-providers-help" | |||||
overlay="Help message!" | overlay="Help message!" | ||||
> | |||||
<div | |||||
className="oauth-providers-help" | |||||
> | |||||
<HelpIcon | |||||
fill="#4b9fd5" | |||||
/> | |||||
</div> | |||||
</Tooltip> | |||||
/> | |||||
</li> | </li> | ||||
`; | `; | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import Checkbox from '../../../components/controls/Checkbox'; | 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 { translate } from '../../../helpers/l10n'; | ||||
import SearchBox from '../../../components/controls/SearchBox'; | import SearchBox from '../../../components/controls/SearchBox'; | ||||
</div> | </div> | ||||
<div className="big-spacer-top"> | <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> | <span className="little-spacer-left">{translate('api_documentation.show_internal')}</span> | ||||
</Checkbox> | </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> | ||||
<div className="spacer-top"> | <div className="spacer-top"> | ||||
<Checkbox checked={showDeprecated} onCheck={onToggleDeprecated}> | |||||
<Checkbox checked={showDeprecated} className="text-middle" onCheck={onToggleDeprecated}> | |||||
<span className="little-spacer-left"> | <span className="little-spacer-left"> | ||||
{translate('api_documentation.show_deprecated')} | {translate('api_documentation.show_deprecated')} | ||||
</span> | </span> | ||||
</Checkbox> | </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> | ||||
</div> | </div> | ||||
); | ); |
> | > | ||||
<Checkbox | <Checkbox | ||||
checked={false} | checked={false} | ||||
className="text-middle" | |||||
onCheck={[Function]} | onCheck={[Function]} | ||||
thirdState={false} | thirdState={false} | ||||
> | > | ||||
api_documentation.show_internal | api_documentation.show_internal | ||||
</span> | </span> | ||||
</Checkbox> | </Checkbox> | ||||
<Tooltip | |||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay="api_documentation.internal_tooltip" | overlay="api_documentation.internal_tooltip" | ||||
> | |||||
<span> | |||||
<HelpIcon | |||||
className="spacer-left text-info" | |||||
/> | |||||
</span> | |||||
</Tooltip> | |||||
/> | |||||
</div> | </div> | ||||
<div | <div | ||||
className="spacer-top" | className="spacer-top" | ||||
> | > | ||||
<Checkbox | <Checkbox | ||||
checked={false} | checked={false} | ||||
className="text-middle" | |||||
onCheck={[Function]} | onCheck={[Function]} | ||||
thirdState={false} | thirdState={false} | ||||
> | > | ||||
api_documentation.show_deprecated | api_documentation.show_deprecated | ||||
</span> | </span> | ||||
</Checkbox> | </Checkbox> | ||||
<Tooltip | |||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay="api_documentation.deprecation_tooltip" | overlay="api_documentation.deprecation_tooltip" | ||||
> | |||||
<span> | |||||
<HelpIcon | |||||
className="spacer-left text-info" | |||||
/> | |||||
</span> | |||||
</Tooltip> | |||||
/> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
`; | `; |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { FormattedMessage } from 'react-intl'; | import { FormattedMessage } from 'react-intl'; | ||||
import { Link } from 'react-router'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
interface Props { | interface Props { | ||||
id={'webhooks.description'} | id={'webhooks.description'} | ||||
values={{ | values={{ | ||||
url: ( | 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> | |||||
) | ) | ||||
}} | }} | ||||
/> | /> |
id="webhooks.description" | id="webhooks.description" | ||||
values={ | values={ | ||||
Object { | 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 | webhooks.documentation_link | ||||
</a>, | |||||
</Link>, | |||||
} | } | ||||
} | } | ||||
/> | /> |
import Level from '../ui/Level'; | import Level from '../ui/Level'; | ||||
import BugIcon from '../icons-components/BugIcon'; | import BugIcon from '../icons-components/BugIcon'; | ||||
import CodeSmellIcon from '../icons-components/CodeSmellIcon'; | import CodeSmellIcon from '../icons-components/CodeSmellIcon'; | ||||
import HelpIcon from '../icons-components/HelpIcon'; | |||||
import HelpTooltip from '../controls/HelpTooltip'; | |||||
import Tooltip from '../controls/Tooltip'; | import Tooltip from '../controls/Tooltip'; | ||||
import VulnerabilityIcon from '../icons-components/VulnerabilityIcon'; | import VulnerabilityIcon from '../icons-components/VulnerabilityIcon'; | ||||
import { BranchLike } from '../../app/types'; | import { BranchLike } from '../../app/types'; | ||||
<CodeSmellIcon className="little-spacer-left" /> | <CodeSmellIcon className="little-spacer-left" /> | ||||
</li> | </li> | ||||
{shouldDisplayHelper && ( | {shouldDisplayHelper && ( | ||||
<Tooltip | |||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay={translateWithParameters( | overlay={translateWithParameters( | ||||
'branches.short_lived.quality_gate.description', | 'branches.short_lived.quality_gate.description', | ||||
totalIssues | totalIssues | ||||
)}> | |||||
<li className="spacer-left"> | |||||
<HelpIcon className="text-info" /> | |||||
</li> | |||||
</Tooltip> | |||||
)} | |||||
tagName="li" | |||||
/> | |||||
)} | )} | ||||
</ul> | </ul> | ||||
); | ); |
className="little-spacer-left" | className="little-spacer-left" | ||||
/> | /> | ||||
</li> | </li> | ||||
<Tooltip | |||||
<HelpTooltip | |||||
className="spacer-left" | |||||
overlay="branches.short_lived.quality_gate.description.1" | overlay="branches.short_lived.quality_gate.description.1" | ||||
> | |||||
<li | |||||
className="spacer-left" | |||||
> | |||||
<HelpIcon | |||||
className="text-info" | |||||
/> | |||||
</li> | |||||
</Tooltip> | |||||
tagName="li" | |||||
/> | |||||
</ul> | </ul> | ||||
`; | `; |
* along with this program; if not, write to the Free Software Foundation, | * along with this program; if not, write to the Free Software Foundation, | ||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * 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; | |||||
} |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | 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> | |||||
); | ); | ||||
} | } |
/* | |||||
* 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> | |||||
); | |||||
} | |||||
} |
* along with this program; if not, write to the Free Software Foundation, | * along with this program; if not, write to the Free Software Foundation, | ||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
.tooltip, | |||||
.popup { | |||||
.tooltip { | |||||
position: absolute; | position: absolute; | ||||
z-index: var(--tooltipZIndex); | z-index: var(--tooltipZIndex); | ||||
display: block; | display: block; | ||||
animation: fadeIn 0.3s forwards; | animation: fadeIn 0.3s forwards; | ||||
} | } | ||||
.popup { | |||||
font-size: var(--baseFontSize); | |||||
font-weight: normal; | |||||
} | |||||
.tooltip.top, | |||||
.popup.top { | |||||
.tooltip.top { | |||||
padding: 5px 0; | padding: 5px 0; | ||||
margin-top: -3px; | margin-top: -3px; | ||||
} | } | ||||
.tooltip.right, | |||||
.popup.right { | |||||
.tooltip.right { | |||||
padding: 0 5px; | padding: 0 5px; | ||||
margin-left: 3px; | margin-left: 3px; | ||||
} | } | ||||
.tooltip.bottom, | |||||
.popup.bottom { | |||||
.tooltip.bottom { | |||||
padding: 5px 0; | padding: 5px 0; | ||||
margin-top: 3px; | margin-top: 3px; | ||||
} | } | ||||
.tooltip.left, | |||||
.popup.left { | |||||
.tooltip.left { | |||||
padding: 0 5px; | padding: 0 5px; | ||||
margin-left: -3px; | margin-left: -3px; | ||||
} | } | ||||
.tooltip-inner, | |||||
.popup-inner { | |||||
.tooltip-inner { | |||||
max-width: 300px; | max-width: 300px; | ||||
text-align: left; | text-align: left; | ||||
text-decoration: none; | text-decoration: none; | ||||
} | } | ||||
.tooltip-inner { | .tooltip-inner { | ||||
padding: 3px 8px; | |||||
padding: 12px 17px; | |||||
color: #fff; | color: #fff; | ||||
background-color: #475760; | background-color: #475760; | ||||
letter-spacing: 0.04em; | 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 { | .tooltip-inner .alert { | ||||
margin-bottom: 5px; | margin-bottom: 5px; | ||||
border-radius: 4px; | border-radius: 4px; | ||||
} | } | ||||
.tooltip-inner a { | .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; | position: absolute; | ||||
width: 0; | width: 0; | ||||
height: 0; | height: 0; | ||||
border: solid transparent; | border: solid transparent; | ||||
} | } | ||||
.tooltip.top .tooltip-arrow, | |||||
.popup.top .popup-arrow, | |||||
.popup.top .popup-arrow::after { | |||||
.tooltip.top .tooltip-arrow { | |||||
bottom: 0; | bottom: 0; | ||||
left: 50%; | left: 50%; | ||||
border-width: 5px 5px 0; | border-width: 5px 5px 0; | ||||
border-top-color: #475760; | 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%; | top: 50%; | ||||
left: 0; | left: 0; | ||||
transform: translateY(-5px); | transform: translateY(-5px); | ||||
border-right-color: #475760; | 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%; | top: 50%; | ||||
right: 0; | right: 0; | ||||
transform: translateY(-5px); | transform: translateY(-5px); | ||||
border-left-color: #475760; | 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; | top: 0; | ||||
left: 50%; | left: 50%; | ||||
transform: translateX(-5px); | transform: translateX(-5px); | ||||
border-bottom-color: #475760; | 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 { | @keyframes fadeIn { | ||||
from { | from { | ||||
opacity: 0; | opacity: 0; |
classNameSpace?: string; | classNameSpace?: string; | ||||
children: React.ReactElement<{}>; | children: React.ReactElement<{}>; | ||||
mouseEnterDelay?: number; | mouseEnterDelay?: number; | ||||
mouseLeaveDelay?: number; | |||||
onShow?: () => void; | onShow?: () => void; | ||||
onHide?: () => void; | onHide?: () => void; | ||||
overlay: React.ReactNode; | overlay: React.ReactNode; | ||||
export class TooltipInner extends React.Component<Props, State> { | export class TooltipInner extends React.Component<Props, State> { | ||||
throttledPositionTooltip: (() => void); | throttledPositionTooltip: (() => void); | ||||
mouseEnterInterval?: number; | mouseEnterInterval?: number; | ||||
mouseLeaveInterval?: number; | |||||
tooltipNode?: HTMLElement | null; | tooltipNode?: HTMLElement | null; | ||||
mounted = false; | mounted = false; | ||||
mouseIn = false; | |||||
static defaultProps = { | static defaultProps = { | ||||
mouseEnterDelay: 0.1 | mouseEnterDelay: 0.1 | ||||
componentWillUnmount() { | componentWillUnmount() { | ||||
this.mounted = false; | this.mounted = false; | ||||
this.removeEventListeners(); | this.removeEventListeners(); | ||||
this.clearIntervals(); | |||||
} | } | ||||
addEventListeners = () => { | addEventListeners = () => { | ||||
window.removeEventListener('scroll', this.throttledPositionTooltip); | window.removeEventListener('scroll', this.throttledPositionTooltip); | ||||
}; | }; | ||||
clearIntervals = () => { | |||||
window.clearInterval(this.mouseEnterInterval); | |||||
window.clearInterval(this.mouseLeaveInterval); | |||||
}; | |||||
isVisible = () => { | isVisible = () => { | ||||
return this.props.visible !== undefined ? this.props.visible : this.state.visible; | return this.props.visible !== undefined ? this.props.visible : this.state.visible; | ||||
}; | }; | ||||
window.clearInterval(this.mouseEnterInterval); | window.clearInterval(this.mouseEnterInterval); | ||||
this.mouseEnterInterval = undefined; | 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() { | render() { | ||||
const { classNameSpace = 'tooltip' } = this.props; | const { classNameSpace = 'tooltip' } = this.props; | ||||
<TooltipPortal> | <TooltipPortal> | ||||
<div | <div | ||||
className={`${classNameSpace} ${this.getPlacement()}`} | className={`${classNameSpace} ${this.getPlacement()}`} | ||||
onMouseEnter={this.handleOverlayMouseEnter} | |||||
onMouseLeave={this.handleOverlayMouseLeave} | |||||
ref={this.tooltipNodeRef} | ref={this.tooltipNodeRef} | ||||
style={ | style={ | ||||
isMeasured(this.state) | isMeasured(this.state) |
expect(onShow).toBeCalled(); | expect(onShow).toBeCalled(); | ||||
wrapper.find('#tooltip').simulate('mouseleave'); | wrapper.find('#tooltip').simulate('mouseleave'); | ||||
jest.runOnlyPendingTimers(); | |||||
wrapper.update(); | |||||
expect(wrapper).toMatchSnapshot(); | expect(wrapper).toMatchSnapshot(); | ||||
expect(onHide).toBeCalled(); | expect(onHide).toBeCalled(); | ||||
}); | }); |
<TooltipPortal> | <TooltipPortal> | ||||
<div | <div | ||||
className="tooltip bottom" | className="tooltip bottom" | ||||
onMouseEnter={[Function]} | |||||
onMouseLeave={[Function]} | |||||
> | > | ||||
<div | <div | ||||
className="tooltip-inner" | className="tooltip-inner" | ||||
<TooltipPortal> | <TooltipPortal> | ||||
<div | <div | ||||
className="tooltip bottom" | className="tooltip bottom" | ||||
onMouseEnter={[Function]} | |||||
onMouseLeave={[Function]} | |||||
> | > | ||||
<div | <div | ||||
className="tooltip-inner" | className="tooltip-inner" |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { getBaseUrl } from '../../helpers/urls'; | |||||
export default function DocImg(props: React.ImgHTMLAttributes<HTMLImageElement>) { | export default function DocImg(props: React.ImgHTMLAttributes<HTMLImageElement>) { | ||||
const { alt, src, ...other } = props; | const { alt, src, ...other } = props; | ||||
if (process.env.NODE_ENV === 'development') { | 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} | |||||
/> | |||||
); | |||||
} | } |
import DocMarkdownBlock from './DocMarkdownBlock'; | import DocMarkdownBlock from './DocMarkdownBlock'; | ||||
interface Props { | interface Props { | ||||
className?: string; | |||||
path: string; | path: string; | ||||
} | } | ||||
}; | }; | ||||
render() { | render() { | ||||
return <DocMarkdownBlock content={this.state.content} />; | |||||
return <DocMarkdownBlock className={this.props.className} content={this.state.content} />; | |||||
} | } | ||||
} | } |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Link } from 'react-router'; | import { Link } from 'react-router'; | ||||
import DetachIcon from '../../components/icons-components/DetachIcon'; | |||||
export default function DocLink(props: React.AnchorHTMLAttributes<HTMLAnchorElement>) { | export default function DocLink(props: React.AnchorHTMLAttributes<HTMLAnchorElement>) { | ||||
const { children, href, ...other } = props; | const { children, href, ...other } = props; | ||||
} | } | ||||
return ( | 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} | |||||
/> | |||||
</> | |||||
); | ); | ||||
} | } |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import * as classNames from 'classnames'; | |||||
import DocMarkdownBlock from './DocMarkdownBlock'; | 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 { | interface Props { | ||||
className?: string; | className?: string; | ||||
children?: React.ReactNode; | |||||
/** Key of the documentation chunk */ | /** Key of the documentation chunk */ | ||||
doc: string; | doc: string; | ||||
} | } | ||||
this.setState({ open: false }); | 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() { | renderOverlay() { | ||||
if (this.state.loading) { | if (this.state.loading) { | ||||
return ( | return ( | ||||
); | ); | ||||
} | } | ||||
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() { | render() { | ||||
return ( | 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> | |||||
); | ); | ||||
} | } | ||||
} | } |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import DocTooltip from '../DocTooltip'; | import DocTooltip from '../DocTooltip'; | ||||
import { click } from '../../../helpers/testUtils'; | |||||
jest.useFakeTimers(); | jest.useFakeTimers(); | ||||
wrapper.setProps({ doc: 'baz' }); | wrapper.setProps({ doc: 'baz' }); | ||||
expect(wrapper.state()).toEqual({ content: undefined, loading: false, open: false }); | 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); | |||||
}); |
// Jest Snapshot v1, https://goo.gl/fbAQLP | // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
exports[`should render simple link 1`] = ` | 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> | |||||
`; | `; |
// Jest Snapshot v1, https://goo.gl/fbAQLP | // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
exports[`should render 1`] = ` | 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`] = ` | 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" | |||||
/> | |||||
} | |||||
/> | |||||
`; | `; |
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import OpenCloseIcon from '../icons-components/OpenCloseIcon'; | 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 { Button } from '../ui/buttons'; | ||||
import { translate, translateWithParameters } from '../../helpers/l10n'; | import { translate, translateWithParameters } from '../../helpers/l10n'; | ||||
if (!this.props.helper) { | if (!this.props.helper) { | ||||
return null; | 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() { | renderValueIndicator() { | ||||
return ( | return ( | ||||
<div className="search-navigator-facet-header-wrapper"> | <div className="search-navigator-facet-header-wrapper"> | ||||
{this.props.onClick ? ( | {this.props.onClick ? ( | ||||
<span className="search-navigator-facet-header"> | |||||
<span className="search-navigator-facet-header display-flex-center"> | |||||
<a href="#" onClick={this.handleClick}> | <a href="#" onClick={this.handleClick}> | ||||
<OpenCloseIcon className="little-spacer-right" open={this.props.open} /> | <OpenCloseIcon className="little-spacer-right" open={this.props.open} /> | ||||
{this.props.name} | {this.props.name} | ||||
{this.renderHelper()} | {this.renderHelper()} | ||||
</span> | </span> | ||||
) : ( | ) : ( | ||||
<span className="search-navigator-facet-header"> | |||||
<span className="search-navigator-facet-header display-flex-center"> | |||||
{this.props.name} | {this.props.name} | ||||
{this.renderHelper()} | {this.renderHelper()} | ||||
</span> | </span> |
className="search-navigator-facet-header-wrapper" | className="search-navigator-facet-header-wrapper" | ||||
> | > | ||||
<span | <span | ||||
className="search-navigator-facet-header" | |||||
className="search-navigator-facet-header display-flex-center" | |||||
> | > | ||||
<a | <a | ||||
href="#" | href="#" | ||||
className="search-navigator-facet-header-wrapper" | className="search-navigator-facet-header-wrapper" | ||||
> | > | ||||
<span | <span | ||||
className="search-navigator-facet-header" | |||||
className="search-navigator-facet-header display-flex-center" | |||||
> | > | ||||
<a | <a | ||||
href="#" | href="#" | ||||
className="search-navigator-facet-header-wrapper" | className="search-navigator-facet-header-wrapper" | ||||
> | > | ||||
<span | <span | ||||
className="search-navigator-facet-header" | |||||
className="search-navigator-facet-header display-flex-center" | |||||
> | > | ||||
<a | <a | ||||
href="#" | href="#" | ||||
className="search-navigator-facet-header-wrapper" | className="search-navigator-facet-header-wrapper" | ||||
> | > | ||||
<span | <span | ||||
className="search-navigator-facet-header" | |||||
className="search-navigator-facet-header display-flex-center" | |||||
> | > | ||||
<a | <a | ||||
href="#" | href="#" | ||||
className="search-navigator-facet-header-wrapper" | className="search-navigator-facet-header-wrapper" | ||||
> | > | ||||
<span | <span | ||||
className="search-navigator-facet-header" | |||||
className="search-navigator-facet-header display-flex-center" | |||||
> | > | ||||
<a | <a | ||||
href="#" | href="#" | ||||
className="search-navigator-facet-header-wrapper" | className="search-navigator-facet-header-wrapper" | ||||
> | > | ||||
<span | <span | ||||
className="search-navigator-facet-header" | |||||
className="search-navigator-facet-header display-flex-center" | |||||
> | > | ||||
foo | foo | ||||
</span> | </span> |
return ( | return ( | ||||
<svg | <svg | ||||
className={className} | className={className} | ||||
width={size} | |||||
height={size} | height={size} | ||||
viewBox="0 0 16 16" | |||||
version="1.1" | 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)"> | <g transform="matrix(0.0364583,0,0,0.0364583,1,-0.166667)"> | ||||
<path | <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" | 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> | </g> | ||||
</svg> | </svg> |
# | # | ||||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | ||||
embed_docs.suggestion=Suggestions For This Page | 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.get_support=Get Support | ||||
embed_docs.stay_connected=Stay Connected | 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 | |||||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | ||||
# | # | ||||
# BRANCHES | # 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=Delete Branch | ||||
branches.delete.are_you_sure=Are you sure you want to delete branch "{0}"? | branches.delete.are_you_sure=Are you sure you want to delete branch "{0}"? | ||||
branches.pull_request.delete=Delete Pull Request | branches.pull_request.delete=Delete Pull Request | ||||
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.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.set_leak_period=Set Leak Period | ||||
branches.last_analysis_date=Last Analysis Date | 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.search_for_branches=Search for branches... | ||||
branches.pull_requests=Pull Requests | 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. | 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. |