aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueBox-test.tsx.snap2
-rw-r--r--server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx1
-rw-r--r--server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotListItem-test.tsx.snap1
-rw-r--r--server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx19
-rw-r--r--server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.tsx63
-rw-r--r--server/sonar-web/src/main/js/components/issue/Issue.tsx8
-rw-r--r--server/sonar-web/src/main/js/components/locations/CrossFileLocationNavigator.tsx23
-rw-r--r--server/sonar-web/src/main/js/components/locations/LocationsList.tsx4
-rw-r--r--server/sonar-web/src/main/js/components/locations/__tests__/CrossFileLocationsNavigator-test.tsx13
-rw-r--r--server/sonar-web/src/main/js/components/locations/__tests__/LocationsList-test.tsx7
-rw-r--r--server/sonar-web/src/main/js/components/locations/__tests__/__snapshots__/LocationsList-test.tsx.snap1
13 files changed, 40 insertions, 109 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.tsx b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.tsx
index 4cadb1885df..a0e5ba847a1 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.tsx
@@ -114,7 +114,6 @@ export default class ConciseIssueBox extends React.PureComponent<Props> {
{selected && (
<LocationsList
locations={locations}
- uniqueKey={issue.key}
isCrossFile={isCrossFile}
onLocationSelect={this.props.onLocationSelect}
scroll={this.props.scroll}
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueBox-test.tsx.snap b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueBox-test.tsx.snap
index a3239afee18..074a4498639 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueBox-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueBox-test.tsx.snap
@@ -61,7 +61,6 @@ exports[`should render correctly 1`] = `
onLocationSelect={[MockFunction]}
scroll={[MockFunction]}
selectedLocationIndex={0}
- uniqueKey="AVsae-CQS-9G3txfbFN2"
/>
</div>
`;
@@ -226,7 +225,6 @@ exports[`should render correctly 2`] = `
onLocationSelect={[MockFunction]}
scroll={[MockFunction]}
selectedLocationIndex={0}
- uniqueKey="AVsae-CQS-9G3txfbFN2"
/>
</div>
`;
diff --git a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx
index 2bd9406c410..5117ef3b3fc 100644
--- a/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx
+++ b/server/sonar-web/src/main/js/apps/issues/crossComponentSourceViewer/CrossComponentSourceViewerWrapper.tsx
@@ -88,9 +88,9 @@ export default class CrossComponentSourceViewerWrapper extends React.PureCompone
this.fetchIssueFlowSnippets(this.props.issue.key);
}
- componentWillReceiveProps(newProps: Props) {
- if (newProps.issue.key !== this.props.issue.key) {
- this.fetchIssueFlowSnippets(newProps.issue.key);
+ componentDidUpdate(prevProps: Props) {
+ if (prevProps.issue.key !== this.props.issue.key) {
+ this.fetchIssueFlowSnippets(this.props.issue.key);
}
}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx
index 3391ea13931..1df6caa33f4 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotListItem.tsx
@@ -62,7 +62,6 @@ export default function HotspotListItem(props: HotspotListItemProps) {
<LocationsList
locations={locations}
isCrossFile={false} // Currently we are not supporting cross file for security hotspot
- uniqueKey={hotspot.key}
onLocationSelect={props.onLocationClick}
selectedLocationIndex={selectedHotspotLocation}
scroll={props.onScroll}
diff --git a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotListItem-test.tsx.snap b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotListItem-test.tsx.snap
index 1da226e22ca..0d13bbb6774 100644
--- a/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotListItem-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/security-hotspots/components/__tests__/__snapshots__/HotspotListItem-test.tsx.snap
@@ -62,7 +62,6 @@ exports[`should render correctly 2`] = `
locations={Array []}
onLocationSelect={[Function]}
scroll={[MockFunction]}
- uniqueKey="01fc972e-2a3c-433e-bcae-0bd7f88f5123"
/>
</a>
`;
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 ba2f5faee85..93950d7fff7 100644
--- a/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx
+++ b/server/sonar-web/src/main/js/components/SourceViewer/SourceViewerBase.tsx
@@ -156,24 +156,13 @@ export default class SourceViewerBase extends React.PureComponent<Props, State>
this.fetchComponent();
}
- componentWillReceiveProps(nextProps: Props) {
- // if a component or a branch has changed,
- // set `loading: true` immediately to avoid unwanted scrolling in `LineCode`
- if (
- nextProps.component !== this.props.component ||
- !isSameBranchLike(nextProps.branchLike, this.props.branchLike)
- ) {
- this.setState({ loading: true });
- }
+ componentDidUpdate(prevProps: Props) {
if (
- nextProps.onIssueSelect !== undefined &&
- nextProps.selectedIssue !== this.props.selectedIssue
+ this.props.onIssueSelect !== undefined &&
+ this.props.selectedIssue !== prevProps.selectedIssue
) {
- this.setState({ selectedIssue: nextProps.selectedIssue });
+ this.setState({ selectedIssue: this.props.selectedIssue });
}
- }
-
- componentDidUpdate(prevProps: Props) {
if (
prevProps.component !== this.props.component ||
!isSameBranchLike(prevProps.branchLike, this.props.branchLike)
diff --git a/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.tsx b/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.tsx
index 21736e0cdff..f9216d65d18 100644
--- a/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.tsx
+++ b/server/sonar-web/src/main/js/components/SourceViewer/components/LineCode.tsx
@@ -22,12 +22,7 @@ import * as React from 'react';
import { LinearIssueLocation, SourceLine } from '../../../types/types';
import LocationIndex from '../../common/LocationIndex';
import Tooltip from '../../controls/Tooltip';
-import {
- highlightIssueLocations,
- highlightSymbol,
- splitByTokens,
- Token
-} from '../helpers/highlight';
+import { highlightIssueLocations, highlightSymbol, splitByTokens } from '../helpers/highlight';
interface Props {
className?: string;
@@ -43,43 +38,17 @@ interface Props {
secondaryIssueLocations: LinearIssueLocation[];
}
-interface State {
- tokens: Token[];
-}
-
-export default class LineCode extends React.PureComponent<React.PropsWithChildren<Props>, State> {
+export default class LineCode extends React.PureComponent<React.PropsWithChildren<Props>> {
activeMarkerNode?: HTMLElement | null;
- codeNode?: HTMLElement | null;
symbols?: NodeListOf<HTMLElement>;
- constructor(props: Props) {
- super(props);
- this.state = {
- tokens: splitByTokens(props.line.code || '')
- };
- }
-
componentDidMount() {
- this.attachEvents();
if (this.props.highlightedLocationMessage && this.activeMarkerNode && this.props.scroll) {
this.props.scroll(this.activeMarkerNode);
}
}
- componentWillReceiveProps(nextProps: Props) {
- if (nextProps.line.code !== this.props.line.code) {
- this.setState({
- tokens: splitByTokens(nextProps.line.code || '')
- });
- }
- }
-
- componentWillUpdate() {
- this.detachEvents();
- }
-
componentDidUpdate(prevProps: Props) {
- this.attachEvents();
if (
this.props.highlightedLocationMessage &&
(!prevProps.highlightedLocationMessage ||
@@ -92,18 +61,20 @@ export default class LineCode extends React.PureComponent<React.PropsWithChildre
}
}
- componentWillUnmount() {
- this.detachEvents();
- }
+ nodeNodeRef = (el: HTMLElement | null) => {
+ if (el) {
+ this.attachEvents(el);
+ } else {
+ this.detachEvents();
+ }
+ };
- attachEvents() {
- if (this.codeNode) {
- this.symbols = this.codeNode.querySelectorAll('.sym');
- if (this.symbols) {
- for (let i = 0; i < this.symbols.length; i++) {
- const symbol = this.symbols[i];
- symbol.addEventListener('click', this.handleSymbolClick);
- }
+ attachEvents(codeNode: HTMLElement) {
+ this.symbols = codeNode.querySelectorAll('.sym');
+ if (this.symbols) {
+ for (let i = 0; i < this.symbols.length; i++) {
+ const symbol = this.symbols[i];
+ symbol.addEventListener('click', this.handleSymbolClick);
}
}
}
@@ -155,7 +126,7 @@ export default class LineCode extends React.PureComponent<React.PropsWithChildre
secondaryIssueLocations
} = this.props;
- let tokens = [...this.state.tokens];
+ let tokens = splitByTokens(this.props.line.code || '');
if (highlightedSymbols) {
highlightedSymbols.forEach(symbol => {
@@ -214,7 +185,7 @@ export default class LineCode extends React.PureComponent<React.PropsWithChildre
data-line-number={line.line}
style={style}>
<div className="source-line-code-inner">
- <pre ref={node => (this.codeNode = node)}>{renderedTokens}</pre>
+ <pre ref={this.nodeNodeRef}>{renderedTokens}</pre>
</div>
{children}
diff --git a/server/sonar-web/src/main/js/components/issue/Issue.tsx b/server/sonar-web/src/main/js/components/issue/Issue.tsx
index ffdcd52f6d1..0d4c0d01ed7 100644
--- a/server/sonar-web/src/main/js/components/issue/Issue.tsx
+++ b/server/sonar-web/src/main/js/components/issue/Issue.tsx
@@ -52,15 +52,11 @@ export default class Issue extends React.PureComponent<Props> {
}
}
- componentWillUpdate(nextProps: Props) {
- if (!nextProps.selected && this.props.selected) {
- this.unbindShortcuts();
- }
- }
-
componentDidUpdate(prevProps: Props) {
if (!prevProps.selected && this.props.selected) {
this.bindShortcuts();
+ } else if (prevProps.selected && !this.props.selected) {
+ this.unbindShortcuts();
}
}
diff --git a/server/sonar-web/src/main/js/components/locations/CrossFileLocationNavigator.tsx b/server/sonar-web/src/main/js/components/locations/CrossFileLocationNavigator.tsx
index bf6074b5a54..8254d91ef50 100644
--- a/server/sonar-web/src/main/js/components/locations/CrossFileLocationNavigator.tsx
+++ b/server/sonar-web/src/main/js/components/locations/CrossFileLocationNavigator.tsx
@@ -20,12 +20,11 @@
import * as React from 'react';
import { translateWithParameters } from '../../helpers/l10n';
import { collapsePath } from '../../helpers/path';
-import SingleFileLocationNavigator from './SingleFileLocationNavigator';
-import './CrossFileLocationNavigator.css';
import { FlowLocation } from '../../types/types';
+import './CrossFileLocationNavigator.css';
+import SingleFileLocationNavigator from './SingleFileLocationNavigator';
interface Props {
- uniqueKey: string;
locations: FlowLocation[];
onLocationSelect: (index: number) => void;
scroll: (element: Element) => void;
@@ -48,18 +47,14 @@ const MAX_PATH_LENGTH = 15;
export default class CrossFileLocationNavigator extends React.PureComponent<Props, State> {
state: State = { collapsed: true };
- componentWillReceiveProps(nextProps: Props) {
- if (nextProps.uniqueKey !== this.props.uniqueKey) {
- this.setState({ collapsed: true });
- }
-
- // expand locations list as soon as a location in the middle of the list is selected
- const { locations: nextLocations } = nextProps;
+ componentDidUpdate() {
+ const { locations, selectedLocationIndex } = this.props;
if (
- nextProps.selectedLocationIndex &&
- nextProps.selectedLocationIndex > 0 &&
- nextLocations !== undefined &&
- nextProps.selectedLocationIndex < nextLocations.length - 1
+ selectedLocationIndex &&
+ selectedLocationIndex > 0 &&
+ locations !== undefined &&
+ selectedLocationIndex < locations.length - 1 &&
+ this.state.collapsed
) {
this.setState({ collapsed: false });
}
diff --git a/server/sonar-web/src/main/js/components/locations/LocationsList.tsx b/server/sonar-web/src/main/js/components/locations/LocationsList.tsx
index 19e52f004c0..65e3c6ebdf2 100644
--- a/server/sonar-web/src/main/js/components/locations/LocationsList.tsx
+++ b/server/sonar-web/src/main/js/components/locations/LocationsList.tsx
@@ -24,7 +24,6 @@ import SingleFileLocationNavigator from './SingleFileLocationNavigator';
interface Props {
isCrossFile: boolean;
- uniqueKey: string;
locations: FlowLocation[];
onLocationSelect: (index: number) => void;
scroll: (element: Element) => void;
@@ -33,7 +32,7 @@ interface Props {
export default class LocationsList extends React.PureComponent<Props> {
render() {
- const { isCrossFile, locations, uniqueKey, selectedLocationIndex } = this.props;
+ const { isCrossFile, locations, selectedLocationIndex } = this.props;
if (!locations || locations.length === 0 || locations.every(location => !location.msg)) {
return null;
@@ -42,7 +41,6 @@ export default class LocationsList extends React.PureComponent<Props> {
if (isCrossFile) {
return (
<CrossFileLocationNavigator
- uniqueKey={uniqueKey}
locations={locations}
onLocationSelect={this.props.onLocationSelect}
scroll={this.props.scroll}
diff --git a/server/sonar-web/src/main/js/components/locations/__tests__/CrossFileLocationsNavigator-test.tsx b/server/sonar-web/src/main/js/components/locations/__tests__/CrossFileLocationsNavigator-test.tsx
index a5f7cd136d3..2147bba7ad4 100644
--- a/server/sonar-web/src/main/js/components/locations/__tests__/CrossFileLocationsNavigator-test.tsx
+++ b/server/sonar-web/src/main/js/components/locations/__tests__/CrossFileLocationsNavigator-test.tsx
@@ -19,8 +19,8 @@
*/
import { shallow } from 'enzyme';
import * as React from 'react';
-import { click } from '../../../helpers/testUtils';
import { mockFlowLocation } from '../../../helpers/testMocks';
+import { click } from '../../../helpers/testUtils';
import { FlowLocation } from '../../../types/types';
import CrossFileLocationsNavigator from '../CrossFileLocationNavigator';
@@ -77,20 +77,9 @@ it('should expand all locations', () => {
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(3);
});
-it('should collapse locations when issue changes', () => {
- const wrapper = shallowRender();
-
- wrapper.setProps({ selectedLocationIndex: 1 });
- expect(wrapper.find('SingleFileLocationNavigator').length).toBe(3);
-
- wrapper.setProps({ uniqueKey: 'def', selectedLocationIndex: undefined });
- expect(wrapper.find('SingleFileLocationNavigator').length).toBe(2);
-});
-
function shallowRender(props: Partial<CrossFileLocationsNavigator['props']> = {}) {
return shallow<CrossFileLocationsNavigator>(
<CrossFileLocationsNavigator
- uniqueKey="abcd"
locations={[location1, location2, location3]}
onLocationSelect={jest.fn()}
scroll={jest.fn()}
diff --git a/server/sonar-web/src/main/js/components/locations/__tests__/LocationsList-test.tsx b/server/sonar-web/src/main/js/components/locations/__tests__/LocationsList-test.tsx
index 3f525e8845c..a5edeafdcf8 100644
--- a/server/sonar-web/src/main/js/components/locations/__tests__/LocationsList-test.tsx
+++ b/server/sonar-web/src/main/js/components/locations/__tests__/LocationsList-test.tsx
@@ -46,23 +46,22 @@ const location3: FlowLocation = {
it('should render locations in the same file', () => {
const locations = [location1, location2];
- expect(shallowRender({ uniqueKey: '', locations, isCrossFile: false })).toMatchSnapshot();
+ expect(shallowRender({ locations, isCrossFile: false })).toMatchSnapshot();
});
it('should render flow locations in different file', () => {
const locations = [location1, location3];
- expect(shallowRender({ uniqueKey: '', locations, isCrossFile: true })).toMatchSnapshot();
+ expect(shallowRender({ locations, isCrossFile: true })).toMatchSnapshot();
});
it('should not render locations', () => {
- const wrapper = shallowRender({ uniqueKey: '', locations: [] });
+ const wrapper = shallowRender({ locations: [] });
expect(wrapper.type()).toBeNull();
});
function shallowRender(overrides: Partial<LocationsList['props']> = {}) {
return shallow<LocationsList>(
<LocationsList
- uniqueKey={mockIssue().key}
locations={mockIssue().secondaryLocations}
isCrossFile={true}
onLocationSelect={jest.fn()}
diff --git a/server/sonar-web/src/main/js/components/locations/__tests__/__snapshots__/LocationsList-test.tsx.snap b/server/sonar-web/src/main/js/components/locations/__tests__/__snapshots__/LocationsList-test.tsx.snap
index 9cb465ba244..eb41475e47b 100644
--- a/server/sonar-web/src/main/js/components/locations/__tests__/__snapshots__/LocationsList-test.tsx.snap
+++ b/server/sonar-web/src/main/js/components/locations/__tests__/__snapshots__/LocationsList-test.tsx.snap
@@ -30,7 +30,6 @@ exports[`should render flow locations in different file 1`] = `
}
onLocationSelect={[MockFunction]}
scroll={[MockFunction]}
- uniqueKey=""
/>
`;