@@ -25,7 +25,7 @@ import DocTooltip from '../../../components/docs/DocTooltip'; | |||
import { getLeakValue } from '../../../components/measure/utils'; | |||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||
import { findMeasure } from '../../../helpers/measures'; | |||
import { getComponentIssuesUrl } from '../../../helpers/urls'; | |||
import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls'; | |||
import { BranchLike } from '../../../types/branch-like'; | |||
import { getIssueIconClass, getIssueMetricKey, IssueType } from '../utils'; | |||
@@ -63,7 +63,11 @@ export function IssueLabel(props: IssueLabelProps) { | |||
) : ( | |||
<Link | |||
className="overview-measures-value text-light" | |||
to={getComponentIssuesUrl(component.key, params)}> | |||
to={ | |||
type === IssueType.SecurityHotspot | |||
? getComponentSecurityHotspotsUrl(component.key, getBranchLikeQuery(branchLike)) | |||
: getComponentIssuesUrl(component.key, params) | |||
}> | |||
{formatMeasure(value, 'SHORT_INT')} | |||
</Link> | |||
)} |
@@ -34,32 +34,44 @@ export interface IssueRatingProps { | |||
useDiffMetric?: boolean; | |||
} | |||
export function IssueRating(props: IssueRatingProps) { | |||
const { branchLike, component, measures, type, useDiffMetric = false } = props; | |||
function renderRatingLink(props: IssueRatingProps) { | |||
const { branchLike, component, useDiffMetric = false, measures, type } = props; | |||
const rating = getIssueRatingMetricKey(type, useDiffMetric); | |||
const measure = findMeasure(measures, rating); | |||
if (!rating || !measure) { | |||
return null; | |||
return ( | |||
<div className="padded"> | |||
<Rating value={undefined} /> | |||
</div> | |||
); | |||
} | |||
const value = useDiffMetric ? getLeakValue(measure) : measure.value; | |||
const value = measure && (useDiffMetric ? getLeakValue(measure) : measure.value); | |||
const tooltip = value && getRatingTooltip(rating, Number(value)); | |||
return ( | |||
<Tooltip overlay={tooltip}> | |||
<span> | |||
<DrilldownLink | |||
branchLike={branchLike} | |||
className="link-no-underline" | |||
component={component.key} | |||
metric={rating}> | |||
<Rating value={value} /> | |||
</DrilldownLink> | |||
</span> | |||
</Tooltip> | |||
); | |||
} | |||
export function IssueRating(props: IssueRatingProps) { | |||
const { type } = props; | |||
return ( | |||
<> | |||
<span className="flex-1 big-spacer-right text-right">{getIssueRatingName(type)}</span> | |||
<Tooltip overlay={tooltip}> | |||
<span> | |||
<DrilldownLink | |||
branchLike={branchLike} | |||
className="link-no-underline" | |||
component={component.key} | |||
metric={rating}> | |||
<Rating value={value} /> | |||
</DrilldownLink> | |||
</span> | |||
</Tooltip> | |||
{renderRatingLink(props)} | |||
</> | |||
); | |||
} |
@@ -44,8 +44,8 @@ it('should render correctly if no values are present', () => { | |||
expect( | |||
shallowRender({ | |||
measures: [mockMeasureEnhanced({ metric: mockMetric({ key: 'NONE' }) })] | |||
}).type() | |||
).toBeNull(); | |||
}) | |||
).toMatchSnapshot(); | |||
}); | |||
function shallowRender(props: Partial<IssueRatingProps> = {}) { |
@@ -120,13 +120,10 @@ exports[`should render correctly for hotspots 1`] = ` | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/project/issues", | |||
"pathname": "/security_hotspots", | |||
"query": Object { | |||
"id": "my-project", | |||
"pullRequest": "1001", | |||
"resolved": "false", | |||
"sinceLeakPeriod": "false", | |||
"types": "SECURITY_HOTSPOT", | |||
}, | |||
} | |||
} | |||
@@ -152,13 +149,10 @@ exports[`should render correctly for hotspots 2`] = ` | |||
style={Object {}} | |||
to={ | |||
Object { | |||
"pathname": "/project/issues", | |||
"pathname": "/security_hotspots", | |||
"query": Object { | |||
"id": "my-project", | |||
"pullRequest": "1001", | |||
"resolved": "false", | |||
"sinceLeakPeriod": "true", | |||
"types": "SECURITY_HOTSPOT", | |||
}, | |||
} | |||
} |
@@ -209,3 +209,18 @@ exports[`should render correctly for vulnerabilities 2`] = ` | |||
</Tooltip> | |||
</Fragment> | |||
`; | |||
exports[`should render correctly if no values are present 1`] = ` | |||
<Fragment> | |||
<span | |||
className="flex-1 big-spacer-right text-right" | |||
> | |||
metric_domain.Reliability | |||
</span> | |||
<div | |||
className="padded" | |||
> | |||
<Rating /> | |||
</div> | |||
</Fragment> | |||
`; |
@@ -175,44 +175,33 @@ export class PullRequestOverview extends React.PureComponent<Props, State> { | |||
</h2> | |||
<div className="overview-panel-content"> | |||
{[IssueType.Bug, IssueType.Vulnerability, IssueType.CodeSmell].map( | |||
(type: IssueType) => ( | |||
<div className="overview-measures-row display-flex-row" key={type}> | |||
<div className="overview-panel-big-padded flex-1 small display-flex-center"> | |||
<IssueLabel | |||
branchLike={branchLike} | |||
component={component} | |||
measures={measures} | |||
type={type} | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
{type === 'VULNERABILITY' && ( | |||
<div className="flex-1 small display-flex-center"> | |||
<IssueLabel | |||
branchLike={branchLike} | |||
component={component} | |||
docTooltip={import( | |||
/* webpackMode: "eager" */ 'Docs/tooltips/metrics/security-hotspots.md' | |||
)} | |||
measures={measures} | |||
type={IssueType.SecurityHotspot} | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
)} | |||
<div className="overview-panel-big-padded overview-measures-aside display-flex-center"> | |||
<IssueRating | |||
branchLike={branchLike} | |||
component={component} | |||
measures={measures} | |||
type={type} | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
{[ | |||
IssueType.Bug, | |||
IssueType.Vulnerability, | |||
IssueType.SecurityHotspot, | |||
IssueType.CodeSmell | |||
].map((type: IssueType) => ( | |||
<div className="overview-measures-row display-flex-row" key={type}> | |||
<div className="overview-panel-big-padded flex-1 small display-flex-center"> | |||
<IssueLabel | |||
branchLike={branchLike} | |||
component={component} | |||
measures={measures} | |||
type={type} | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
) | |||
)} | |||
<div className="overview-panel-big-padded overview-measures-aside display-flex-center"> | |||
<IssueRating | |||
branchLike={branchLike} | |||
component={component} | |||
measures={measures} | |||
type={type} | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
</div> | |||
))} | |||
{[MeasurementType.Coverage, MeasurementType.Duplication].map( | |||
(type: MeasurementType) => ( |
@@ -483,7 +483,125 @@ exports[`should render correctly for a failed QG 1`] = ` | |||
/> | |||
</div> | |||
<div | |||
className="flex-1 small display-flex-center" | |||
className="overview-panel-big-padded overview-measures-aside display-flex-center" | |||
> | |||
<Memo(IssueRating) | |||
branchLike={ | |||
Object { | |||
"analysisDate": "2018-01-01", | |||
"base": "master", | |||
"branch": "feature/foo/bar", | |||
"key": "1001", | |||
"target": "master", | |||
"title": "Foo Bar feature", | |||
} | |||
} | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
measures={ | |||
Array [ | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_bugs", | |||
"key": "new_bugs", | |||
"name": "new_bugs", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_vulnerabilities", | |||
"key": "new_vulnerabilities", | |||
"name": "new_vulnerabilities", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_code_smells", | |||
"key": "new_code_smells", | |||
"name": "new_code_smells", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_security_hotspots", | |||
"key": "new_security_hotspots", | |||
"name": "new_security_hotspots", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
] | |||
} | |||
type="VULNERABILITY" | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
</div> | |||
<div | |||
className="overview-measures-row display-flex-row" | |||
key="SECURITY_HOTSPOT" | |||
> | |||
<div | |||
className="overview-panel-big-padded flex-1 small display-flex-center" | |||
> | |||
<Memo(IssueLabel) | |||
branchLike={ | |||
@@ -519,7 +637,6 @@ exports[`should render correctly for a failed QG 1`] = ` | |||
"tags": Array [], | |||
} | |||
} | |||
docTooltip={Promise {}} | |||
measures={ | |||
Array [ | |||
Object { | |||
@@ -705,7 +822,7 @@ exports[`should render correctly for a failed QG 1`] = ` | |||
}, | |||
] | |||
} | |||
type="VULNERABILITY" | |||
type="SECURITY_HOTSPOT" | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
@@ -1745,7 +1862,125 @@ exports[`should render correctly for a passed QG 1`] = ` | |||
/> | |||
</div> | |||
<div | |||
className="flex-1 small display-flex-center" | |||
className="overview-panel-big-padded overview-measures-aside display-flex-center" | |||
> | |||
<Memo(IssueRating) | |||
branchLike={ | |||
Object { | |||
"analysisDate": "2018-01-01", | |||
"base": "master", | |||
"branch": "feature/foo/bar", | |||
"key": "1001", | |||
"target": "master", | |||
"title": "Foo Bar feature", | |||
} | |||
} | |||
component={ | |||
Object { | |||
"breadcrumbs": Array [], | |||
"key": "my-project", | |||
"name": "MyProject", | |||
"organization": "foo", | |||
"qualifier": "TRK", | |||
"qualityGate": Object { | |||
"isDefault": true, | |||
"key": "30", | |||
"name": "Sonar way", | |||
}, | |||
"qualityProfiles": Array [ | |||
Object { | |||
"deleted": false, | |||
"key": "my-qp", | |||
"language": "ts", | |||
"name": "Sonar way", | |||
}, | |||
], | |||
"tags": Array [], | |||
} | |||
} | |||
measures={ | |||
Array [ | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_bugs", | |||
"key": "new_bugs", | |||
"name": "new_bugs", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_vulnerabilities", | |||
"key": "new_vulnerabilities", | |||
"name": "new_vulnerabilities", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_code_smells", | |||
"key": "new_code_smells", | |||
"name": "new_code_smells", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
Object { | |||
"bestValue": true, | |||
"metric": Object { | |||
"id": "new_security_hotspots", | |||
"key": "new_security_hotspots", | |||
"name": "new_security_hotspots", | |||
"type": "PERCENT", | |||
}, | |||
"periods": Array [ | |||
Object { | |||
"bestValue": true, | |||
"index": 1, | |||
"value": "1.0", | |||
}, | |||
], | |||
"value": "1.0", | |||
}, | |||
] | |||
} | |||
type="VULNERABILITY" | |||
useDiffMetric={true} | |||
/> | |||
</div> | |||
</div> | |||
<div | |||
className="overview-measures-row display-flex-row" | |||
key="SECURITY_HOTSPOT" | |||
> | |||
<div | |||
className="overview-panel-big-padded flex-1 small display-flex-center" | |||
> | |||
<Memo(IssueLabel) | |||
branchLike={ | |||
@@ -1781,7 +2016,6 @@ exports[`should render correctly for a passed QG 1`] = ` | |||
"tags": Array [], | |||
} | |||
} | |||
docTooltip={Promise {}} | |||
measures={ | |||
Array [ | |||
Object { | |||
@@ -1967,7 +2201,7 @@ exports[`should render correctly for a passed QG 1`] = ` | |||
}, | |||
] | |||
} | |||
type="VULNERABILITY" | |||
type="SECURITY_HOTSPOT" | |||
useDiffMetric={true} | |||
/> | |||
</div> |
@@ -88,6 +88,7 @@ export const PR_METRICS: string[] = [ | |||
MetricKey.new_reliability_rating, | |||
MetricKey.new_vulnerabilities, | |||
MetricKey.new_security_hotspots, | |||
MetricKey.new_security_review_rating, | |||
MetricKey.new_security_rating | |||
]; | |||
@@ -165,9 +166,10 @@ const ISSUETYPE_MAP = { | |||
[IssueType.SecurityHotspot]: { | |||
metric: MetricKey.security_hotspots, | |||
newMetric: MetricKey.new_security_hotspots, | |||
rating: '', | |||
newRating: '', | |||
ratingName: '', | |||
rating: MetricKey.security_review_rating, | |||
newRating: MetricKey.new_security_review_rating, | |||
ratingName: 'SecurityReview', | |||
iconClass: SecurityHotspotIcon | |||
} | |||
}; |
@@ -18,13 +18,9 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import BugIcon from 'sonar-ui-common/components/icons/BugIcon'; | |||
import CodeSmellIcon from 'sonar-ui-common/components/icons/CodeSmellIcon'; | |||
import SecurityHotspotIcon from 'sonar-ui-common/components/icons/SecurityHotspotIcon'; | |||
import VulnerabilityIcon from 'sonar-ui-common/components/icons/VulnerabilityIcon'; | |||
import Rating from 'sonar-ui-common/components/ui/Rating'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import Measure from '../../../components/measure/Measure'; | |||
import ProjectCardRatingMeasure from './ProjectCardRatingMeasure'; | |||
interface Props { | |||
measures: T.Dict<string>; | |||
@@ -33,77 +29,38 @@ interface Props { | |||
export default function ProjectCardLeakMeasures({ measures }: Props) { | |||
return ( | |||
<div className="project-card-leak-measures"> | |||
<div className="project-card-measure" data-key="new_reliability_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_bugs" | |||
metricType="SHORT_INT" | |||
value={measures['new_bugs']} | |||
/> | |||
<Rating value={measures['new_reliability_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<BugIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.bugs.name')} | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel={translate('metric.bugs.name')} | |||
measures={measures} | |||
metricKey="new_bugs" | |||
metricRatingKey="new_reliability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div className="project-card-measure" data-key="new_security_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_vulnerabilities" | |||
metricType="SHORT_INT" | |||
value={measures['new_vulnerabilities']} | |||
/> | |||
<Rating value={measures['new_security_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<VulnerabilityIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.vulnerabilities.name')} | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel={translate('metric.vulnerabilities.name')} | |||
measures={measures} | |||
metricKey="new_vulnerabilities" | |||
metricRatingKey="new_security_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div className="project-card-measure" data-key="new_security_review_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_security_hotspots_reviewed" | |||
metricType="PERCENT" | |||
value={measures['new_security_hotspots_reviewed']} | |||
/> | |||
<Rating value={measures['new_security_review_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<SecurityHotspotIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.security_hotspots_reviewed.extra_short_name')} | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconKey="security_hotspots" | |||
iconLabel={translate('projects.security_hotspots_reviewed')} | |||
measures={measures} | |||
metricKey="new_security_hotspots_reviewed" | |||
metricRatingKey="new_security_review_rating" | |||
metricType="PERCENT" | |||
/> | |||
<div className="project-card-measure" data-key="new_maintainability_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_code_smells" | |||
metricType="SHORT_INT" | |||
value={measures['new_code_smells']} | |||
/> | |||
<Rating value={measures['new_maintainability_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<CodeSmellIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.code_smells.name')} | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel={translate('metric.code_smells.name')} | |||
measures={measures} | |||
metricKey="new_code_smells" | |||
metricRatingKey="new_maintainability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
{measures['new_coverage'] != null && ( | |||
<div className="project-card-measure" data-key="new_coverage"> |
@@ -18,17 +18,13 @@ | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
import * as React from 'react'; | |||
import BugIcon from 'sonar-ui-common/components/icons/BugIcon'; | |||
import CodeSmellIcon from 'sonar-ui-common/components/icons/CodeSmellIcon'; | |||
import SecurityHotspotIcon from 'sonar-ui-common/components/icons/SecurityHotspotIcon'; | |||
import VulnerabilityIcon from 'sonar-ui-common/components/icons/VulnerabilityIcon'; | |||
import DuplicationsRating from 'sonar-ui-common/components/ui/DuplicationsRating'; | |||
import Rating from 'sonar-ui-common/components/ui/Rating'; | |||
import SizeRating from 'sonar-ui-common/components/ui/SizeRating'; | |||
import { translate } from 'sonar-ui-common/helpers/l10n'; | |||
import Measure from '../../../components/measure/Measure'; | |||
import CoverageRating from '../../../components/ui/CoverageRating'; | |||
import ProjectCardLanguagesContainer from './ProjectCardLanguagesContainer'; | |||
import ProjectCardRatingMeasure from './ProjectCardRatingMeasure'; | |||
interface Props { | |||
measures: T.Dict<string | undefined>; | |||
@@ -46,77 +42,39 @@ export default function ProjectCardOverallMeasures({ measures }: Props) { | |||
return ( | |||
<div className="project-card-measures"> | |||
<div className="project-card-measure" data-key="reliability_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="bugs" | |||
metricType="SHORT_INT" | |||
value={measures['bugs']} | |||
/> | |||
<Rating value={measures['reliability_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<BugIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.bugs.name')} | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel={translate('metric.bugs.name')} | |||
measures={measures} | |||
metricKey="bugs" | |||
metricRatingKey="reliability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div className="project-card-measure" data-key="security_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="vulnerabilities" | |||
metricType="SHORT_INT" | |||
value={measures['vulnerabilities']} | |||
/> | |||
<Rating value={measures['security_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<VulnerabilityIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.vulnerabilities.name')} | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel={translate('metric.vulnerabilities.name')} | |||
measures={measures} | |||
metricKey="vulnerabilities" | |||
metricRatingKey="security_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div className="project-card-measure" data-key="security_review_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="security_hotspots_reviewed" | |||
metricType="PERCENT" | |||
value={measures['security_hotspots_reviewed']} | |||
/> | |||
<Rating value={measures['security_review_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<SecurityHotspotIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.security_hotspots_reviewed.extra_short_name')} | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconKey="security_hotspots" | |||
iconLabel={translate('projects.security_hotspots_reviewed')} | |||
measures={measures} | |||
metricKey="security_hotspots_reviewed" | |||
metricRatingKey="security_review_rating" | |||
metricType="PERCENT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconLabel={translate('metric.code_smells.name')} | |||
measures={measures} | |||
metricKey="code_smells" | |||
metricRatingKey="sqale_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div className="project-card-measure" data-key="sqale_rating"> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="code_smells" | |||
metricType="SHORT_INT" | |||
value={measures['code_smells']} | |||
/> | |||
<Rating value={measures['sqale_rating']} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<CodeSmellIcon className="little-spacer-right text-bottom" /> | |||
{translate('metric.code_smells.name')} | |||
</div> | |||
</div> | |||
</div> | |||
{measures['coverage'] != null && ( | |||
<div className="project-card-measure" data-key="coverage"> | |||
<div className="project-card-measure-inner"> |
@@ -0,0 +1,59 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 IssueTypeIcon from 'sonar-ui-common/components/icons/IssueTypeIcon'; | |||
import Rating from 'sonar-ui-common/components/ui/Rating'; | |||
import Measure from '../../../components/measure/Measure'; | |||
export interface ProjectCardRatingMeasureProps { | |||
iconKey?: string; | |||
iconLabel: string; | |||
measures: T.Dict<string | undefined>; | |||
metricKey: string; | |||
metricRatingKey: string; | |||
metricType: string; | |||
} | |||
export default function ProjectCardRatingMeasure(props: ProjectCardRatingMeasureProps) { | |||
const { iconKey, iconLabel, measures, metricKey, metricRatingKey, metricType } = props; | |||
return ( | |||
<div className="project-card-measure" data-key={metricRatingKey}> | |||
<div className="project-card-measure-inner"> | |||
<div className="project-card-measure-number"> | |||
<Measure | |||
className="spacer-right" | |||
metricKey={metricKey} | |||
metricType={metricType} | |||
value={measures[metricKey]} | |||
/> | |||
<Rating value={measures[metricRatingKey]} /> | |||
</div> | |||
<div className="project-card-measure-label-with-icon"> | |||
<IssueTypeIcon className="little-spacer-right text-bottom" query={iconKey || metricKey} /> | |||
{iconLabel} | |||
</div> | |||
</div> | |||
</div> | |||
); | |||
} |
@@ -0,0 +1,47 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2020 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 { shallow } from 'enzyme'; | |||
import * as React from 'react'; | |||
import ProjectCardRatingMeasure, { | |||
ProjectCardRatingMeasureProps | |||
} from '../ProjectCardRatingMeasure'; | |||
it('renders', () => { | |||
expect(shallowRender()).toMatchSnapshot(); | |||
expect(shallowRender({ iconKey: 'overriddenIconKey' })).toMatchSnapshot('iconKey'); | |||
}); | |||
function shallowRender(overrides: Partial<ProjectCardRatingMeasureProps> = {}) { | |||
const measures = { | |||
security_rating: '1', | |||
vulnerabilities: '0', | |||
dummyThatShouldBeIgnored: 'yes' | |||
}; | |||
return shallow( | |||
<ProjectCardRatingMeasure | |||
iconLabel="label" | |||
measures={measures} | |||
metricKey="vulnerabilities" | |||
metricRatingKey="security_rating" | |||
metricType="SHORT_INT" | |||
{...overrides} | |||
/> | |||
); | |||
} |
@@ -4,123 +4,87 @@ exports[`should render correctly with all data 1`] = ` | |||
<div | |||
className="project-card-leak-measures" | |||
> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_reliability_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_bugs" | |||
metricType="SHORT_INT" | |||
value="8" | |||
/> | |||
<Rating | |||
value="1.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<BugIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.bugs.name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_security_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_vulnerabilities" | |||
metricType="SHORT_INT" | |||
value="2" | |||
/> | |||
<Rating | |||
value="2.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<VulnerabilityIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.vulnerabilities.name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_security_review_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_security_hotspots_reviewed" | |||
metricType="PERCENT" | |||
/> | |||
<Rating /> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<SecurityHotspotIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.security_hotspots_reviewed.extra_short_name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_maintainability_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_code_smells" | |||
metricType="SHORT_INT" | |||
value="0" | |||
/> | |||
<Rating | |||
value="1.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<CodeSmellIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.code_smells.name | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.bugs.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_coverage": "26.55", | |||
"new_duplicated_lines_density": "0.55", | |||
"new_lines": "87", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_bugs" | |||
metricRatingKey="new_reliability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.vulnerabilities.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_coverage": "26.55", | |||
"new_duplicated_lines_density": "0.55", | |||
"new_lines": "87", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_vulnerabilities" | |||
metricRatingKey="new_security_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconKey="security_hotspots" | |||
iconLabel="projects.security_hotspots_reviewed" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_coverage": "26.55", | |||
"new_duplicated_lines_density": "0.55", | |||
"new_lines": "87", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_security_hotspots_reviewed" | |||
metricRatingKey="new_security_review_rating" | |||
metricType="PERCENT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.code_smells.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_coverage": "26.55", | |||
"new_duplicated_lines_density": "0.55", | |||
"new_lines": "87", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_code_smells" | |||
metricRatingKey="new_maintainability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_coverage" | |||
@@ -197,123 +161,75 @@ exports[`should render no data style new coverage, new duplications and new line | |||
<div | |||
className="project-card-leak-measures" | |||
> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_reliability_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_bugs" | |||
metricType="SHORT_INT" | |||
value="8" | |||
/> | |||
<Rating | |||
value="1.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<BugIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.bugs.name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_security_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_vulnerabilities" | |||
metricType="SHORT_INT" | |||
value="2" | |||
/> | |||
<Rating | |||
value="2.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<VulnerabilityIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.vulnerabilities.name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_security_review_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_security_hotspots_reviewed" | |||
metricType="PERCENT" | |||
/> | |||
<Rating /> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<SecurityHotspotIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.security_hotspots_reviewed.extra_short_name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_maintainability_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="new_code_smells" | |||
metricType="SHORT_INT" | |||
value="0" | |||
/> | |||
<Rating | |||
value="1.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<CodeSmellIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.code_smells.name | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.bugs.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_bugs" | |||
metricRatingKey="new_reliability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.vulnerabilities.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_vulnerabilities" | |||
metricRatingKey="new_security_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconKey="security_hotspots" | |||
iconLabel="projects.security_hotspots_reviewed" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_security_hotspots_reviewed" | |||
metricRatingKey="new_security_review_rating" | |||
metricType="PERCENT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.code_smells.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"new_bugs": "8", | |||
"new_code_smells": "0", | |||
"new_maintainability_rating": "1.0", | |||
"new_reliability_rating": "1.0", | |||
"new_security_rating": "2.0", | |||
"new_vulnerabilities": "2", | |||
} | |||
} | |||
metricKey="new_code_smells" | |||
metricRatingKey="new_maintainability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div | |||
className="project-card-measure" | |||
data-key="new_duplicated_lines_density" |
@@ -4,123 +4,87 @@ exports[`should render correctly with all data 1`] = ` | |||
<div | |||
className="project-card-measures" | |||
> | |||
<div | |||
className="project-card-measure" | |||
data-key="reliability_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="bugs" | |||
metricType="SHORT_INT" | |||
value="17" | |||
/> | |||
<Rating | |||
value="1.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<BugIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.bugs.name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="security_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="vulnerabilities" | |||
metricType="SHORT_INT" | |||
value="0" | |||
/> | |||
<Rating | |||
value="1.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<VulnerabilityIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.vulnerabilities.name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="security_review_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="security_hotspots_reviewed" | |||
metricType="PERCENT" | |||
/> | |||
<Rating /> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<SecurityHotspotIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.security_hotspots_reviewed.extra_short_name | |||
</div> | |||
</div> | |||
</div> | |||
<div | |||
className="project-card-measure" | |||
data-key="sqale_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="code_smells" | |||
metricType="SHORT_INT" | |||
value="132" | |||
/> | |||
<Rating | |||
value="1.0" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<CodeSmellIcon | |||
className="little-spacer-right text-bottom" | |||
/> | |||
metric.code_smells.name | |||
</div> | |||
</div> | |||
</div> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.bugs.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"bugs": "17", | |||
"code_smells": "132", | |||
"coverage": "88.3", | |||
"duplicated_lines_density": "9.8", | |||
"ncloc": "2053", | |||
"reliability_rating": "1.0", | |||
"security_rating": "1.0", | |||
"sqale_rating": "1.0", | |||
"vulnerabilities": "0", | |||
} | |||
} | |||
metricKey="bugs" | |||
metricRatingKey="reliability_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.vulnerabilities.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"bugs": "17", | |||
"code_smells": "132", | |||
"coverage": "88.3", | |||
"duplicated_lines_density": "9.8", | |||
"ncloc": "2053", | |||
"reliability_rating": "1.0", | |||
"security_rating": "1.0", | |||
"sqale_rating": "1.0", | |||
"vulnerabilities": "0", | |||
} | |||
} | |||
metricKey="vulnerabilities" | |||
metricRatingKey="security_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconKey="security_hotspots" | |||
iconLabel="projects.security_hotspots_reviewed" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"bugs": "17", | |||
"code_smells": "132", | |||
"coverage": "88.3", | |||
"duplicated_lines_density": "9.8", | |||
"ncloc": "2053", | |||
"reliability_rating": "1.0", | |||
"security_rating": "1.0", | |||
"sqale_rating": "1.0", | |||
"vulnerabilities": "0", | |||
} | |||
} | |||
metricKey="security_hotspots_reviewed" | |||
metricRatingKey="security_review_rating" | |||
metricType="PERCENT" | |||
/> | |||
<ProjectCardRatingMeasure | |||
iconLabel="metric.code_smells.name" | |||
measures={ | |||
Object { | |||
"alert_status": "ERROR", | |||
"bugs": "17", | |||
"code_smells": "132", | |||
"coverage": "88.3", | |||
"duplicated_lines_density": "9.8", | |||
"ncloc": "2053", | |||
"reliability_rating": "1.0", | |||
"security_rating": "1.0", | |||
"sqale_rating": "1.0", | |||
"vulnerabilities": "0", | |||
} | |||
} | |||
metricKey="code_smells" | |||
metricRatingKey="sqale_rating" | |||
metricType="SHORT_INT" | |||
/> | |||
<div | |||
className="project-card-measure" | |||
data-key="coverage" |
@@ -0,0 +1,69 @@ | |||
// Jest Snapshot v1, https://goo.gl/fbAQLP | |||
exports[`renders 1`] = ` | |||
<div | |||
className="project-card-measure" | |||
data-key="security_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="vulnerabilities" | |||
metricType="SHORT_INT" | |||
value="0" | |||
/> | |||
<Rating | |||
value="1" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<IssueTypeIcon | |||
className="little-spacer-right text-bottom" | |||
query="vulnerabilities" | |||
/> | |||
label | |||
</div> | |||
</div> | |||
</div> | |||
`; | |||
exports[`renders: iconKey 1`] = ` | |||
<div | |||
className="project-card-measure" | |||
data-key="security_rating" | |||
> | |||
<div | |||
className="project-card-measure-inner" | |||
> | |||
<div | |||
className="project-card-measure-number" | |||
> | |||
<Measure | |||
className="spacer-right" | |||
metricKey="vulnerabilities" | |||
metricType="SHORT_INT" | |||
value="0" | |||
/> | |||
<Rating | |||
value="1" | |||
/> | |||
</div> | |||
<div | |||
className="project-card-measure-label-with-icon" | |||
> | |||
<IssueTypeIcon | |||
className="little-spacer-right text-bottom" | |||
query="overriddenIconKey" | |||
/> | |||
label | |||
</div> | |||
</div> | |||
</div> | |||
`; |
@@ -77,8 +77,8 @@ export function getComponentIssuesUrl(componentKey: string, query?: Query): Loca | |||
/** | |||
* Generate URL for a component's security hotspot page | |||
*/ | |||
export function getComponentSecurityHotspotsUrl(componentKey: string): Location { | |||
return { pathname: '/security_hotspots', query: { id: componentKey } }; | |||
export function getComponentSecurityHotspotsUrl(componentKey: string, query: Query = {}): Location { | |||
return { pathname: '/security_hotspots', query: { ...query, id: componentKey } }; | |||
} | |||
/** |
@@ -968,6 +968,7 @@ projects.sort.-duplications=by duplications (worst first) | |||
projects.sort.size=by size (smallest first) | |||
projects.sort.-size=by size (biggest first) | |||
projects.security_hotspots_reviewed=Hotspots Reviewed | |||
#------------------------------------------------------------------------------ | |||
# | |||
@@ -2223,7 +2224,10 @@ metric.security_hotspots.description=Security Hotspots | |||
metric.security_hotspots.name=Security Hotspots | |||
metric.security_hotspots_reviewed.description=Percentage of Security Hotspots Reviewed | |||
metric.security_hotspots_reviewed.name=Security Hotspots Reviewed | |||
metric.security_hotspots_reviewed.extra_short_name=Hotspots Reviewed | |||
metric.security_hotspots_reviewed_status.description=Security Review Reviewed Status | |||
metric.security_hotspots_reviewed_status.name=Security Review Reviewed Status | |||
metric.security_hotspots_to_review_status.description=Security Review To Review Status | |||
metric.security_hotspots_to_review_status.name=Security Review To Review Status | |||
metric.security_rating.description=Security rating | |||
metric.security_rating.name=Security Rating | |||
metric.security_rating.extra_short_name=Rating |