@@ -18,16 +18,19 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import { FormattedMessage } from 'react-intl'; | |||
import { ButtonLink } from '../../../components/controls/buttons'; | |||
import Tooltip from '../../../components/controls/Tooltip'; | |||
import { translate, translateWithParameters } from '../../../helpers/l10n'; | |||
import { RuleStatus } from '../../../types/rules'; | |||
import DocumentationTooltip from '../../common/DocumentationTooltip'; | |||
import SonarLintIcon from '../../icons/SonarLintIcon'; | |||
import { WorkspaceContextShape } from '../../workspace/context'; | |||
export interface IssueMessageProps { | |||
engine?: string; | |||
engineName?: string; | |||
quickFixAvailable?: boolean; | |||
manualVulnerability: boolean; | |||
message: string; | |||
onOpenRule: WorkspaceContextShape['openRule']; | |||
@@ -36,12 +39,42 @@ export interface IssueMessageProps { | |||
} | |||
export default function IssueMessage(props: IssueMessageProps) { | |||
const { engine, engineName, manualVulnerability, message, ruleKey, ruleStatus } = props; | |||
const { | |||
engine, | |||
engineName, | |||
quickFixAvailable, | |||
manualVulnerability, | |||
message, | |||
ruleKey, | |||
ruleStatus | |||
} = props; | |||
const ruleEngine = engineName ? engineName : engine; | |||
return ( | |||
<div className="issue-message break-word"> | |||
<div className="display-inline-flex-center issue-message break-word"> | |||
<span className="spacer-right">{message}</span> | |||
{quickFixAvailable && ( | |||
<Tooltip | |||
overlay={ | |||
<FormattedMessage | |||
id="issue.quick_fix_available_with_sonarlint" | |||
defaultMessage={translate('issue.quick_fix_available_with_sonarlint')} | |||
values={{ | |||
link: ( | |||
<a | |||
href="https://www.sonarqube.org/sonarlint/?referrer=sonarqube-quick-fix" | |||
rel="noopener noreferrer" | |||
target="_blank"> | |||
SonarLint | |||
</a> | |||
) | |||
}} | |||
/> | |||
} | |||
mouseLeaveDelay={0.5}> | |||
<SonarLintIcon className="spacer-right" size={15} /> | |||
</Tooltip> | |||
)} | |||
<ButtonLink | |||
aria-label={translate('issue.why_this_issue.long')} | |||
className="issue-see-rule spacer-right text-baseline" | |||
@@ -52,7 +85,6 @@ export default function IssueMessage(props: IssueMessageProps) { | |||
}> | |||
{translate('issue.why_this_issue')} | |||
</ButtonLink> | |||
{ruleStatus && (ruleStatus === RuleStatus.Deprecated || ruleStatus === RuleStatus.Removed) && ( | |||
<DocumentationTooltip | |||
className="spacer-left" | |||
@@ -68,7 +100,6 @@ export default function IssueMessage(props: IssueMessageProps) { | |||
</span> | |||
</DocumentationTooltip> | |||
)} | |||
{ruleEngine && ( | |||
<Tooltip overlay={translateWithParameters('issue.from_external_rule_engine', ruleEngine)}> | |||
<div className="badge spacer-right text-baseline">{ruleEngine}</div> |
@@ -81,6 +81,7 @@ export default function IssueTitleBar(props: IssueTitleBarProps) { | |||
externalRulesRepoNames && | |||
externalRulesRepoNames[issue.externalRuleEngine] | |||
} | |||
quickFixAvailable={issue.quickFixAvailable} | |||
manualVulnerability={issue.fromHotspot && issue.type === 'VULNERABILITY'} | |||
message={issue.message} | |||
onOpenRule={openRule} |
@@ -27,6 +27,7 @@ import IssueMessage, { IssueMessageProps } from '../IssueMessage'; | |||
it('should render correctly', () => { | |||
expect(shallowRender()).toMatchSnapshot('default'); | |||
expect(shallowRender({ engine: 'js' })).toMatchSnapshot('with engine info'); | |||
expect(shallowRender({ quickFixAvailable: true })).toMatchSnapshot('with quick fix'); | |||
expect(shallowRender({ engineName: 'JS' })).toMatchSnapshot('with engine name'); | |||
expect(shallowRender({ manualVulnerability: true })).toMatchSnapshot('is manual vulnerability'); | |||
expect(shallowRender({ ruleStatus: RuleStatus.Deprecated })).toMatchSnapshot( |
@@ -2,7 +2,7 @@ | |||
exports[`should render correctly: default 1`] = ` | |||
<div | |||
className="issue-message break-word" | |||
className="display-inline-flex-center issue-message break-word" | |||
> | |||
<span | |||
className="spacer-right" | |||
@@ -21,7 +21,7 @@ exports[`should render correctly: default 1`] = ` | |||
exports[`should render correctly: is deprecated rule 1`] = ` | |||
<div | |||
className="issue-message break-word" | |||
className="display-inline-flex-center issue-message break-word" | |||
> | |||
<span | |||
className="spacer-right" | |||
@@ -58,7 +58,7 @@ exports[`should render correctly: is deprecated rule 1`] = ` | |||
exports[`should render correctly: is manual vulnerability 1`] = ` | |||
<div | |||
className="issue-message break-word" | |||
className="display-inline-flex-center issue-message break-word" | |||
> | |||
<span | |||
className="spacer-right" | |||
@@ -86,7 +86,7 @@ exports[`should render correctly: is manual vulnerability 1`] = ` | |||
exports[`should render correctly: is removed rule 1`] = ` | |||
<div | |||
className="issue-message break-word" | |||
className="display-inline-flex-center issue-message break-word" | |||
> | |||
<span | |||
className="spacer-right" | |||
@@ -123,7 +123,7 @@ exports[`should render correctly: is removed rule 1`] = ` | |||
exports[`should render correctly: with engine info 1`] = ` | |||
<div | |||
className="issue-message break-word" | |||
className="display-inline-flex-center issue-message break-word" | |||
> | |||
<span | |||
className="spacer-right" | |||
@@ -151,7 +151,7 @@ exports[`should render correctly: with engine info 1`] = ` | |||
exports[`should render correctly: with engine name 1`] = ` | |||
<div | |||
className="issue-message break-word" | |||
className="display-inline-flex-center issue-message break-word" | |||
> | |||
<span | |||
className="spacer-right" | |||
@@ -176,3 +176,47 @@ exports[`should render correctly: with engine name 1`] = ` | |||
</Tooltip> | |||
</div> | |||
`; | |||
exports[`should render correctly: with quick fix 1`] = ` | |||
<div | |||
className="display-inline-flex-center issue-message break-word" | |||
> | |||
<span | |||
className="spacer-right" | |||
> | |||
Reduce the number of conditional operators (4) used in the expression | |||
</span> | |||
<Tooltip | |||
mouseLeaveDelay={0.5} | |||
overlay={ | |||
<FormattedMessage | |||
defaultMessage="issue.quick_fix_available_with_sonarlint" | |||
id="issue.quick_fix_available_with_sonarlint" | |||
values={ | |||
Object { | |||
"link": <a | |||
href="https://www.sonarqube.org/sonarlint/?referrer=sonarqube-quick-fix" | |||
rel="noopener noreferrer" | |||
target="_blank" | |||
> | |||
SonarLint | |||
</a>, | |||
} | |||
} | |||
/> | |||
} | |||
> | |||
<SonarLintIcon | |||
className="spacer-right" | |||
size={15} | |||
/> | |||
</Tooltip> | |||
<ButtonLink | |||
aria-label="issue.why_this_issue.long" | |||
className="issue-see-rule spacer-right text-baseline" | |||
onClick={[Function]} | |||
> | |||
issue.why_this_issue | |||
</ButtonLink> | |||
</div> | |||
`; |
@@ -343,6 +343,7 @@ declare namespace T { | |||
effort?: string; | |||
externalRuleEngine?: string; | |||
fromExternalRule?: boolean; | |||
quickFixAvailable?: boolean; | |||
key: string; | |||
flows: FlowLocation[][]; | |||
fromHotspot: boolean; |
@@ -808,6 +808,7 @@ issue.assign.assigned_to_x_click_to_change=Assigned to {0}, click to change | |||
issue.assign.unassigned_click_to_assign=Unassigned, click to assign issue | |||
issue.assign.formlink=Assign | |||
issue.assign.to_me=to me | |||
issue.quick_fix_available_with_sonarlint=Quick fix available in {link} | |||
issue.comment.add_comment=Add Comment | |||
issue.comment.formlink=Comment | |||
issue.comment.submit=Comment |