aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js')
-rw-r--r--server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js135
1 files changed, 76 insertions, 59 deletions
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js
index fb98c06ab15..d0b5eff25b0 100644
--- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js
+++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerCode.js
@@ -19,8 +19,7 @@
*/
// @flow
import React from 'react';
-import SourceViewerLine from './SourceViewerLine';
-import { TooltipsContainer } from '../mixins/tooltips-mixin';
+import Line from './components/Line';
import { translate } from '../../helpers/l10n';
import type { Duplication, SourceLine } from './types';
import type { Issue } from '../issue/types';
@@ -64,24 +63,19 @@ export default class SourceViewerCode extends React.PureComponent {
onDuplicationClick: (number, number) => void,
onIssueSelect: (string) => void,
onIssueUnselect: () => void,
- onLineClick: (number, HTMLElement) => void,
+ onIssuesOpen: (SourceLine) => void,
+ onIssuesClose: (SourceLine) => void,
+ onLineClick: (SourceLine, HTMLElement) => void,
onSCMClick: (SourceLine, HTMLElement) => void,
- onSelectLocation: (flowIndex: number, locationIndex: number) => void,
+ onLocationSelect: (flowIndex: number, locationIndex: number) => void,
onSymbolClick: (string) => void,
+ openIssuesByLine: { [number]: boolean },
selectedIssue: string | null,
selectedIssueLocation: IndexedIssueLocation | null,
sources: Array<SourceLine>,
symbolsByLine: { [number]: Array<string> }
};
- isSCMChanged (s: SourceLine, p: null | SourceLine) {
- let changed = true;
- if (p != null && s.scmAuthor != null && p.scmAuthor != null) {
- changed = (s.scmAuthor !== p.scmAuthor) || (s.scmDate !== p.scmDate);
- }
- return changed;
- }
-
getDuplicationsForLine (line: SourceLine) {
return this.props.duplicationsByLine[line.line] || EMPTY_ARRAY;
}
@@ -103,7 +97,8 @@ export default class SourceViewerCode extends React.PureComponent {
}
getSecondaryIssueLocationMessagesForLine (line: SourceLine, issueKey: string) {
- return this.props.issueSecondaryLocationMessagesByIssueByLine[issueKey][line.line] || EMPTY_ARRAY;
+ return this.props.issueSecondaryLocationMessagesByIssueByLine[issueKey][line.line] ||
+ EMPTY_ARRAY;
}
renderLine = (
@@ -116,10 +111,12 @@ export default class SourceViewerCode extends React.PureComponent {
) => {
const { filterLine, selectedIssue, sources } = this.props;
const filtered = filterLine ? filterLine(line) : null;
- const secondaryIssueLocations = selectedIssue ?
- this.getSecondaryIssueLocationsForLine(line, selectedIssue) : EMPTY_ARRAY;
- const secondaryIssueLocationMessages = selectedIssue ?
- this.getSecondaryIssueLocationMessagesForLine(line, selectedIssue) : EMPTY_ARRAY;
+ const secondaryIssueLocations = selectedIssue
+ ? this.getSecondaryIssueLocationsForLine(line, selectedIssue)
+ : EMPTY_ARRAY;
+ const secondaryIssueLocationMessages = selectedIssue
+ ? this.getSecondaryIssueLocationMessagesForLine(line, selectedIssue)
+ : EMPTY_ARRAY;
const duplicationsCount = this.props.duplications ? this.props.duplications.length : 0;
@@ -128,28 +125,32 @@ export default class SourceViewerCode extends React.PureComponent {
// for the following properties pass null if the line for sure is not impacted
const symbolsForLine = this.props.symbolsByLine[line.line] || [];
const { highlightedSymbol } = this.props;
- const optimizedHighlightedSymbol = highlightedSymbol != null && symbolsForLine.includes(highlightedSymbol) ?
- highlightedSymbol : null;
+ const optimizedHighlightedSymbol = highlightedSymbol != null &&
+ symbolsForLine.includes(highlightedSymbol)
+ ? highlightedSymbol
+ : null;
- const optimizedSelectedIssue = selectedIssue != null && issuesForLine.includes(selectedIssue) ?
- selectedIssue : null;
+ const optimizedSelectedIssue = selectedIssue != null && issuesForLine.includes(selectedIssue)
+ ? selectedIssue
+ : null;
const { selectedIssueLocation } = this.props;
- const optimizedSelectedIssueLocation =
- selectedIssueLocation != null &&
- secondaryIssueLocations.some(location =>
+ const optimizedSelectedIssueLocation = selectedIssueLocation != null &&
+ secondaryIssueLocations.some(
+ location =>
location.flowIndex === selectedIssueLocation.flowIndex &&
location.locationIndex === selectedIssueLocation.locationIndex
- ) ? selectedIssueLocation : null;
+ )
+ ? selectedIssueLocation
+ : null;
return (
- <SourceViewerLine
+ <Line
displayAllIssues={this.props.displayAllIssues}
displayCoverage={displayCoverage}
displayDuplications={displayDuplications}
displayFiltered={displayFiltered}
displayIssues={displayIssues}
- displaySCM={this.isSCMChanged(line, index > 0 ? sources[index - 1] : null)}
duplications={this.getDuplicationsForLine(line)}
duplicationsCount={duplicationsCount}
filtered={filtered}
@@ -165,9 +166,13 @@ export default class SourceViewerCode extends React.PureComponent {
onDuplicationClick={this.props.onDuplicationClick}
onIssueSelect={this.props.onIssueSelect}
onIssueUnselect={this.props.onIssueUnselect}
+ onIssuesOpen={this.props.onIssuesOpen}
+ onIssuesClose={this.props.onIssuesClose}
onSCMClick={this.props.onSCMClick}
- onSelectLocation={this.props.onSelectLocation}
+ onLocationSelect={this.props.onLocationSelect}
onSymbolClick={this.props.onSymbolClick}
+ openIssues={this.props.openIssuesByLine[line.line] || false}
+ previousLine={index > 0 ? sources[index - 1] : undefined}
secondaryIssueLocations={secondaryIssueLocations}
secondaryIssueLocationMessages={secondaryIssueLocationMessages}
selectedIssue={optimizedSelectedIssue}
@@ -187,48 +192,60 @@ export default class SourceViewerCode extends React.PureComponent {
return (
<div>
- {this.props.hasSourcesBefore && (
+ {this.props.hasSourcesBefore &&
<div className="source-viewer-more-code">
- {this.props.loadingSourcesBefore ? (
- <div className="js-component-viewer-loading-before">
+ {this.props.loadingSourcesBefore
+ ? <div className="js-component-viewer-loading-before">
<i className="spinner"/>
- <span className="note spacer-left">{translate('source_viewer.loading_more_code')}</span>
+ <span className="note spacer-left">
+ {translate('source_viewer.loading_more_code')}
+ </span>
</div>
- ) : (
- <button className="js-component-viewer-source-before" onClick={this.props.loadSourcesBefore}>
+ : <button
+ className="js-component-viewer-source-before"
+ onClick={this.props.loadSourcesBefore}>
{translate('source_viewer.load_more_code')}
- </button>
+ </button>}
+ </div>}
+
+ <table className="source-table">
+ <tbody>
+ {hasFileIssues &&
+ this.renderLine(
+ ZERO_LINE,
+ -1,
+ hasCoverage,
+ hasDuplications,
+ displayFiltered,
+ hasIssues
)}
- </div>
- )}
-
- <TooltipsContainer>
- <table className="source-table">
- <tbody>
- {hasFileIssues && (
- this.renderLine(ZERO_LINE, -1, hasCoverage, hasDuplications, displayFiltered, hasIssues)
- )}
- {sources.map((line, index) => (
- this.renderLine(line, index, hasCoverage, hasDuplications, displayFiltered, hasIssues)
+ {sources.map((line, index) =>
+ this.renderLine(
+ line,
+ index,
+ hasCoverage,
+ hasDuplications,
+ displayFiltered,
+ hasIssues
))}
- </tbody>
- </table>
- </TooltipsContainer>
+ </tbody>
+ </table>
- {this.props.hasSourcesAfter && (
+ {this.props.hasSourcesAfter &&
<div className="source-viewer-more-code">
- {this.props.loadingSourcesAfter ? (
- <div className="js-component-viewer-loading-after">
+ {this.props.loadingSourcesAfter
+ ? <div className="js-component-viewer-loading-after">
<i className="spinner"/>
- <span className="note spacer-left">{translate('source_viewer.loading_more_code')}</span>
+ <span className="note spacer-left">
+ {translate('source_viewer.loading_more_code')}
+ </span>
</div>
- ) : (
- <button className="js-component-viewer-source-after" onClick={this.props.loadSourcesAfter}>
+ : <button
+ className="js-component-viewer-source-after"
+ onClick={this.props.loadSourcesAfter}>
{translate('source_viewer.load_more_code')}
- </button>
- )}
- </div>
- )}
+ </button>}
+ </div>}
</div>
);
}