From f1d6dd1b1b818717baf0f2cf8f3248f0aad3731b Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Mon, 4 Nov 2019 09:35:56 +0900 Subject: [PATCH] SONAR-12050 show issues' locations marker in CodeViewer --- .../issues/components/IssuesSourceViewer.tsx | 2 ++ .../IssuesSourceViewer-test.tsx.snap | 2 ++ .../SourceViewer/SourceViewerBase.tsx | 6 ++++ .../SourceViewer/SourceViewerCode.tsx | 4 +++ .../SourceViewerBase-test.tsx.snap | 2 ++ .../SourceViewer/components/Line.tsx | 4 +++ .../SourceViewer/components/LineCode.tsx | 4 +++ .../components/LineIssuesList.tsx | 4 +++ .../src/main/js/components/issue/Issue.css | 2 +- .../src/main/js/components/issue/Issue.tsx | 4 +++ .../main/js/components/issue/IssueView.tsx | 4 +++ .../issue/components/IssueTitleBar.tsx | 34 ++++++++++++++++++- .../__tests__/IssueTitleBar-test.tsx | 12 +++++++ .../__snapshots__/IssueTitleBar-test.tsx.snap | 6 ++++ 14 files changed, 88 insertions(+), 2 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx index 81f3f2621bc..91786a16985 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.tsx @@ -134,6 +134,8 @@ export default class IssuesSourceViewer extends React.PureComponent { branchLike={this.props.branchLike} component={component} displayAllIssues={true} + displayIssueLocationsCount={true} + displayIssueLocationsLink={false} displayLocationMarkers={!allMessagesEmpty} highlightedLocationMessage={highlightedLocationMessage} highlightedLocations={highlightedLocations} diff --git a/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap index 416ec4a47fd..723c6c1aa3c 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/issues/components/__tests__/__snapshots__/IssuesSourceViewer-test.tsx.snap @@ -279,6 +279,8 @@ exports[`should render SourceViewer correctly 1`] = ` } component="main.js" displayAllIssues={true} + displayIssueLocationsCount={true} + displayIssueLocationsLink={false} displayLocationMarkers={false} highlightedLocations={Array []} loadIssues={[MockFunction]} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx index da2db7965d4..22b82d5f11a 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx @@ -57,6 +57,8 @@ export interface Props { branchLike: T.BranchLike | undefined; component: string; displayAllIssues?: boolean; + displayIssueLocationsCount?: boolean; + displayIssueLocationsLink?: boolean; displayLocationMarkers?: boolean; highlightedLine?: number; // `undefined` elements mean they are located in a different file, @@ -123,6 +125,8 @@ export default class SourceViewerBase extends React.PureComponent static defaultProps = { displayAllIssues: false, + displayIssueLocationsCount: true, + displayIssueLocationsLink: true, displayLocationMarkers: true, loadComponent: defaultLoadComponent, loadIssues: defaultLoadIssues, @@ -612,6 +616,8 @@ export default class SourceViewerBase extends React.PureComponent branchLike={this.props.branchLike} componentKey={this.props.component} displayAllIssues={this.props.displayAllIssues} + displayIssueLocationsCount={this.props.displayIssueLocationsCount} + displayIssueLocationsLink={this.props.displayIssueLocationsLink} displayLocationMarkers={this.props.displayLocationMarkers} duplications={this.state.duplications} duplicationsByLine={this.state.duplicationsByLine} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx index 075a44be474..d6c8104533e 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.tsx @@ -41,6 +41,8 @@ interface Props { branchLike: T.BranchLike | undefined; componentKey: string; displayAllIssues?: boolean; + displayIssueLocationsCount?: boolean; + displayIssueLocationsLink?: boolean; displayLocationMarkers?: boolean; duplications: T.Duplication[] | undefined; duplicationsByLine: { [line: number]: number[] }; @@ -119,6 +121,8 @@ export default class SourceViewerCode extends React.PureComponent { displayAllIssues={this.props.displayAllIssues} displayCoverage={displayCoverage} displayDuplications={displayDuplications} + displayIssueLocationsCount={this.props.displayIssueLocationsCount} + displayIssueLocationsLink={this.props.displayIssueLocationsLink} displayIssues={displayIssues} displayLocationMarkers={this.props.displayLocationMarkers} duplications={this.getDuplicationsForLine(line)} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap index 66538d4b69b..91750341a24 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/SourceViewer/__tests__/__snapshots__/SourceViewerBase-test.tsx.snap @@ -11,6 +11,8 @@ exports[`should render correctly 1`] = ` } component="my-component" displayAllIssues={false} + displayIssueLocationsCount={true} + displayIssueLocationsLink={true} displayLocationMarkers={true} loadComponent={[Function]} loadIssues={[Function]} diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx index cc86553eeb5..793c1384180 100644 --- a/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx +++ b/server/sonar-web/src/main/js/components/SourceViewer/components/Line.tsx @@ -34,6 +34,8 @@ interface Props { displayAllIssues?: boolean; displayCoverage: boolean; displayDuplications: boolean; + displayIssueLocationsCount?: boolean; + displayIssueLocationsLink?: boolean; displayIssues: boolean; displayLocationMarkers?: boolean; duplications: number[]; @@ -153,6 +155,8 @@ export default class Line extends React.PureComponent { { {showIssues && issues.length > 0 && ( void; @@ -38,6 +40,8 @@ export default function LineIssuesList(props: Props) { {props.issues.map(issue => ( void; onCheck?: (issue: string) => void; @@ -130,6 +132,8 @@ export default class Issue extends React.PureComponent { branchLike={this.props.branchLike} checked={this.props.checked} currentPopup={this.props.openPopup} + displayLocationsCount={this.props.displayLocationsCount} + displayLocationsLink={this.props.displayLocationsLink} issue={this.props.issue} onAssign={this.handleAssignement} onChange={this.props.onChange} diff --git a/server/sonar-web/src/main/js/components/issue/IssueView.tsx b/server/sonar-web/src/main/js/components/issue/IssueView.tsx index d78f5df9e1c..19fd1bea80a 100644 --- a/server/sonar-web/src/main/js/components/issue/IssueView.tsx +++ b/server/sonar-web/src/main/js/components/issue/IssueView.tsx @@ -30,6 +30,8 @@ interface Props { branchLike?: T.BranchLike; checked?: boolean; currentPopup?: string; + displayLocationsCount?: boolean; + displayLocationsLink?: boolean; issue: T.Issue; onAssign: (login: string) => void; onChange: (issue: T.Issue) => void; @@ -83,6 +85,8 @@ export default class IssueView extends React.PureComponent { void; togglePopup: (popup: string, show?: boolean) => void; @@ -40,6 +45,22 @@ export default function IssueTitleBar(props: Props) { const { issue } = props; const hasSimilarIssuesFilter = props.onFilter != null; + const locationsCount = + issue.secondaryLocations.length + + issue.flows.reduce((sum, locations) => sum + locations.length, 0); + + const locationsBadge = ( + + {locationsCount} + + ); + + const displayLocations = props.displayLocationsCount && locationsCount > 0; + const issueUrl = getComponentIssuesUrl(issue.project, { ...getBranchLikeQuery(props.branchLike), issues: issue.key, @@ -79,6 +100,17 @@ export default function IssueTitleBar(props: Props) { )} + {displayLocations && ( +
  • + {props.displayLocationsLink ? ( + + {locationsBadge} + + ) : ( + locationsBadge + )} +
  • + )}
  • { const branch: T.ShortLivingBranch = { @@ -44,6 +45,17 @@ it('should render the titlebar with the filter', () => { expect(element).toMatchSnapshot(); }); +it('should count all code locations', () => { + const element = shallow( + + ); + expect(element.find('LocationIndex')).toMatchSnapshot(); +}); + it('should have a correct permalink for security hotspots', () => { const wrapper = shallow( diff --git a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.tsx.snap b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.tsx.snap index 812027acb3b..3fc0b16bfe3 100644 --- a/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.tsx.snap +++ b/server/sonar-web/src/main/js/components/issue/components/__tests__/__snapshots__/IssueTitleBar-test.tsx.snap @@ -1,5 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should count all code locations 1`] = ` + + 7 + +`; + exports[`should render the titlebar correctly 1`] = `