aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-web/src/main/js/apps/issues/actions.js15
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/App.js27
-rw-r--r--server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js7
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssue.js4
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.js13
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationBadge.js7
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocations.js61
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigator.js13
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigatorLocation.js5
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesList.js4
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssue-test.js.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocationBadge-test.js.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocations-test.js.snap25
-rw-r--r--server/sonar-web/src/main/js/apps/issues/styles.css16
-rw-r--r--server/sonar-web/src/main/js/components/common/LocationIndex.js16
-rw-r--r--server/sonar-web/src/main/js/helpers/issues.js8
16 files changed, 176 insertions, 47 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/actions.js b/server/sonar-web/src/main/js/apps/issues/actions.js
index 69bc8192302..610628b15ff 100644
--- a/server/sonar-web/src/main/js/apps/issues/actions.js
+++ b/server/sonar-web/src/main/js/apps/issues/actions.js
@@ -22,6 +22,8 @@ import type { State } from './components/App';
export const enableLocationsNavigator = (state: State) => ({
locationsNavigator: true,
+ selectedFlowIndex: state.selectedFlowIndex ||
+ (state.openIssue && state.openIssue.flows.length > 0 ? 0 : null),
selectedLocationIndex: state.selectedLocationIndex || 0
});
@@ -47,12 +49,13 @@ export const selectLocation = (nextIndex: ?number) => (state: State) => {
};
export const selectNextLocation = (state: State) => {
- const { selectedLocationIndex: index, openIssue } = state;
+ const { selectedFlowIndex, selectedLocationIndex: index, openIssue } = state;
if (openIssue) {
+ const locations = selectedFlowIndex != null
+ ? openIssue.flows[selectedFlowIndex]
+ : openIssue.secondaryLocations;
return {
- selectedLocationIndex: index != null && openIssue.secondaryLocations.length > index + 1
- ? index + 1
- : index
+ selectedLocationIndex: index != null && locations.length > index + 1 ? index + 1 : index
};
}
};
@@ -63,3 +66,7 @@ export const selectPreviousLocation = (state: State) => {
return { selectedLocationIndex: index != null && index > 0 ? index - 1 : index };
}
};
+
+export const selectFlow = (nextIndex: ?number) => () => {
+ return { selectedFlowIndex: nextIndex, selectedLocationIndex: 0 };
+};
diff --git a/server/sonar-web/src/main/js/apps/issues/components/App.js b/server/sonar-web/src/main/js/apps/issues/components/App.js
index 4fac9bbe264..1b7f6a9f952 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/App.js
+++ b/server/sonar-web/src/main/js/apps/issues/components/App.js
@@ -89,6 +89,7 @@ export type State = {
referencedRules: { [string]: { name: string } },
referencedUsers: { [string]: ReferencedUser },
selected?: string,
+ selectedFlowIndex: ?number,
selectedLocationIndex: ?number
};
@@ -117,6 +118,7 @@ export default class App extends React.PureComponent {
referencedRules: {},
referencedUsers: {},
selected: getOpen(props.location.query),
+ selectedFlowIndex: null,
selectedLocationIndex: null
};
}
@@ -137,11 +139,15 @@ export default class App extends React.PureComponent {
const openIssue = this.getOpenIssue(nextProps, this.state.issues);
if (openIssue != null && openIssue.key !== this.state.selected) {
- this.setState({ selected: openIssue.key, selectedLocationIndex: null });
+ this.setState({
+ selected: openIssue.key,
+ selectedFlowIndex: null,
+ selectedLocationIndex: null
+ });
}
if (openIssue == null) {
- this.setState({ selectedLocationIndex: null });
+ this.setState({ selectedFlowIndex: null, selectedLocationIndex: null });
}
this.setState({
@@ -252,7 +258,11 @@ export default class App extends React.PureComponent {
if (this.state.openIssue) {
this.openIssue(issues[selectedIndex + 1].key);
} else {
- this.setState({ selected: issues[selectedIndex + 1].key, selectedLocationIndex: null });
+ this.setState({
+ selected: issues[selectedIndex + 1].key,
+ selectedFlowIndex: null,
+ selectedLocationIndex: null
+ });
}
}
};
@@ -264,7 +274,11 @@ export default class App extends React.PureComponent {
if (this.state.openIssue) {
this.openIssue(issues[selectedIndex - 1].key);
} else {
- this.setState({ selected: issues[selectedIndex - 1].key, selectedLocationIndex: null });
+ this.setState({
+ selected: issues[selectedIndex - 1].key,
+ selectedFlowIndex: null,
+ selectedLocationIndex: null
+ });
}
}
};
@@ -372,6 +386,7 @@ export default class App extends React.PureComponent {
selected: issues.length > 0
? openIssue != null ? openIssue.key : issues[0].key
: undefined,
+ selectedFlowIndex: null,
selectedLocationIndex: null
});
}
@@ -560,6 +575,7 @@ export default class App extends React.PureComponent {
selectLocation = (index: ?number) => this.setState(actions.selectLocation(index));
selectNextLocation = () => this.setState(actions.selectNextLocation);
selectPreviousLocation = () => this.setState(actions.selectPreviousLocation);
+ selectFlow = (index: ?number) => this.setState(actions.selectFlow(index));
renderBulkChange(openIssue: ?Issue) {
const { component, currentUser } = this.props;
@@ -649,9 +665,11 @@ export default class App extends React.PureComponent {
/>
<ConciseIssuesList
issues={issues}
+ onFlowSelect={this.selectFlow}
onIssueSelect={this.openIssue}
onLocationSelect={this.selectLocation}
selected={this.state.selected}
+ selectedFlowIndex={this.state.selectedFlowIndex}
selectedLocationIndex={this.state.selectedLocationIndex}
/>
{paging != null &&
@@ -755,6 +773,7 @@ export default class App extends React.PureComponent {
onIssueChange={this.handleIssueChange}
onIssueSelect={this.openIssue}
onLocationSelect={this.selectLocation}
+ selectedFlowIndex={this.state.selectedFlowIndex}
selectedLocationIndex={
this.state.locationsNavigator ? this.state.selectedLocationIndex : null
}
diff --git a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js
index dc1de955664..9c321fb007c 100644
--- a/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js
+++ b/server/sonar-web/src/main/js/apps/issues/components/IssuesSourceViewer.js
@@ -29,6 +29,7 @@ type Props = {|
onIssueSelect: string => void,
onLocationSelect: number => void,
openIssue: Issue,
+ selectedFlowIndex: ?number,
selectedLocationIndex: ?number
|};
@@ -58,9 +59,11 @@ export default class IssuesSourceViewer extends React.PureComponent {
};
render() {
- const { openIssue, selectedLocationIndex } = this.props;
+ const { openIssue, selectedFlowIndex, selectedLocationIndex } = this.props;
- const locations = openIssue.secondaryLocations;
+ const locations = selectedFlowIndex != null
+ ? openIssue.flows[selectedFlowIndex]
+ : openIssue.flows.length > 0 ? openIssue.flows[0] : openIssue.secondaryLocations;
const locationMessage = locations != null &&
selectedLocationIndex != null &&
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssue.js b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssue.js
index d6c1662c2e6..5fdeec3da53 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssue.js
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssue.js
@@ -25,11 +25,13 @@ import type { Issue } from '../../../components/issue/types';
type Props = {|
issue: Issue,
+ onFlowSelect: number => void,
onLocationSelect: number => void,
onSelect: string => void,
previousIssue: ?Issue,
scroll: HTMLElement => void,
selected: boolean,
+ selectedFlowIndex: ?number,
selectedLocationIndex: ?number
|};
@@ -47,9 +49,11 @@ export default class ConciseIssue extends React.PureComponent {
<ConciseIssueBox
issue={issue}
onClick={this.props.onSelect}
+ onFlowSelect={this.props.onFlowSelect}
onLocationSelect={this.props.onLocationSelect}
scroll={this.props.scroll}
selected={selected}
+ selectedFlowIndex={selected ? this.props.selectedFlowIndex : null}
selectedLocationIndex={selected ? this.props.selectedLocationIndex : null}
/>
</div>
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.js b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.js
index da7f573a062..bff17414951 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.js
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueBox.js
@@ -29,9 +29,11 @@ import type { Issue } from '../../../components/issue/types';
type Props = {|
issue: Issue,
onClick: string => void,
+ onFlowSelect: number => void,
onLocationSelect: number => void,
scroll: HTMLElement => void,
selected: boolean,
+ selectedFlowIndex: ?number,
selectedLocationIndex: ?number
|};
@@ -66,20 +68,27 @@ export default class ConciseIssueBox extends React.PureComponent {
: { onClick: this.handleClick, role: 'listitem', tabIndex: 0 };
return (
- <div className={classNames('concise-issue-box', { selected })} {...clickAttributes}>
+ <div
+ className={classNames('concise-issue-box', 'clearfix', { selected })}
+ {...clickAttributes}>
<div className="concise-issue-box-message" ref={node => (this.node = node)}>
{issue.message}
</div>
<div className="concise-issue-box-attributes">
<TypeHelper type={issue.type} />
<SeverityHelper className="big-spacer-left" severity={issue.severity} />
- <ConciseIssueLocations issue={issue} />
+ <ConciseIssueLocations
+ issue={issue}
+ onFlowSelect={this.props.onFlowSelect}
+ selectedFlowIndex={this.props.selectedFlowIndex}
+ />
</div>
{selected &&
<ConciseIssueLocationsNavigator
issue={issue}
onLocationSelect={this.props.onLocationSelect}
scroll={this.props.scroll}
+ selectedFlowIndex={this.props.selectedFlowIndex}
selectedLocationIndex={this.props.selectedLocationIndex}
/>}
</div>
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationBadge.js b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationBadge.js
index 0eb9223eafe..ae19b8f367f 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationBadge.js
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationBadge.js
@@ -25,17 +25,20 @@ import { translateWithParameters } from '../../../helpers/l10n';
import { formatMeasure } from '../../../helpers/measures';
type Props = {|
- count: number
+ count: number,
+ onClick?: () => void,
+ selected?: boolean
|};
export default function ConciseIssueLocationBadge(props: Props) {
return (
<Tooltip
+ mouseEnterDelay={0.5}
overlay={translateWithParameters(
'issue.this_issue_involves_x_code_locations',
formatMeasure(props.count)
)}>
- <LocationIndex>
+ <LocationIndex onClick={props.onClick} selected={props.selected}>
{'+'}{props.count}
</LocationIndex>
</Tooltip>
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocations.js b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocations.js
index e3563ade3d9..cf1144a24bc 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocations.js
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocations.js
@@ -23,22 +23,67 @@ import ConciseIssueLocationBadge from './ConciseIssueLocationBadge';
import type { Issue } from '../../../components/issue/types';
type Props = {|
- issue: Issue
+ issue: Issue,
+ onFlowSelect: number => void,
+ selectedFlowIndex: ?number
|};
+type State = {
+ collapsed: boolean
+};
+
+const LIMIT = 3;
+
export default class ConciseIssueLocations extends React.PureComponent {
props: Props;
+ state: State = { collapsed: true };
+
+ handleExpandClick = (event: Event) => {
+ event.preventDefault();
+ this.setState({ collapsed: false });
+ };
+
+ renderExpandButton() {
+ return (
+ <a className="little-spacer-left link-no-underline" href="#" onClick={this.handleExpandClick}>
+ ...
+ </a>
+ );
+ }
render() {
const { secondaryLocations, flows } = this.props.issue;
- return (
- <div className="pull-right">
- {secondaryLocations.length > 0 &&
- <ConciseIssueLocationBadge count={secondaryLocations.length} />}
+ const badges = [];
- {flows.map((flow, index) => <ConciseIssueLocationBadge key={index} count={flow.length} />)}
- </div>
- );
+ if (secondaryLocations.length > 0) {
+ badges.push(
+ <ConciseIssueLocationBadge
+ key="-1"
+ count={secondaryLocations.length}
+ selected={this.props.selectedFlowIndex == null}
+ />
+ );
+ }
+
+ flows.forEach((flow, index) => {
+ badges.push(
+ <ConciseIssueLocationBadge
+ key={index}
+ count={flow.length}
+ onClick={() => this.props.onFlowSelect(index)}
+ selected={index === this.props.selectedFlowIndex}
+ />
+ );
+ });
+
+ return this.state.collapsed
+ ? <div className="concise-issue-locations pull-right">
+ {badges.slice(0, LIMIT)}
+ {badges.length > LIMIT && this.renderExpandButton()}
+ </div>
+ : <div className="concise-issue-locations spacer-top">
+ {badges}
+ </div>;
}
}
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigator.js b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigator.js
index 7bac7593484..ebe8aff7935 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigator.js
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigator.js
@@ -26,6 +26,7 @@ type Props = {|
issue: Issue,
onLocationSelect: number => void,
scroll: HTMLElement => void,
+ selectedFlowIndex: ?number,
selectedLocationIndex: ?number
|};
@@ -38,16 +39,20 @@ export default class ConciseIssueLocationsNavigator extends React.PureComponent
};
render() {
- const { selectedLocationIndex } = this.props;
- const { secondaryLocations } = this.props.issue;
+ const { selectedFlowIndex, selectedLocationIndex } = this.props;
+ const { flows, secondaryLocations } = this.props.issue;
- if (secondaryLocations.length === 0) {
+ const locations = selectedFlowIndex != null
+ ? flows[selectedFlowIndex]
+ : flows.length > 0 ? flows[0] : secondaryLocations;
+
+ if (locations == null || locations.length === 0) {
return null;
}
return (
<div className="spacer-top">
- {secondaryLocations.map((location, index) => (
+ {locations.map((location, index) => (
<ConciseIssueLocationsNavigatorLocation
key={index}
index={index}
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigatorLocation.js b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigatorLocation.js
index e76a1ccdcc0..099e7804d2c 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigatorLocation.js
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssueLocationsNavigatorLocation.js
@@ -54,7 +54,10 @@ export default class ConciseIssueLocationsNavigatorLocation extends React.PureCo
render() {
return (
<div className="little-spacer-top" ref={node => (this.node = node)}>
- <a className="link-no-underline" href="#" onClick={this.handleClick}>
+ <a
+ className="consice-issue-locations-navigator-location"
+ href="#"
+ onClick={this.handleClick}>
<LocationIndex selected={this.props.selected}>
{this.props.index + 1}
</LocationIndex>
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesList.js b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesList.js
index 8eae0760686..18e9018a6f5 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesList.js
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/ConciseIssuesList.js
@@ -25,9 +25,11 @@ import type { Issue } from '../../../components/issue/types';
type Props = {|
issues: Array<Issue>,
+ onFlowSelect: number => void,
onIssueSelect: string => void,
onLocationSelect: number => void,
selected?: string,
+ selectedFlowIndex: ?number,
selectedLocationIndex: ?number
|};
@@ -48,11 +50,13 @@ export default class ConciseIssuesList extends React.PureComponent {
<ConciseIssue
key={issue.key}
issue={issue}
+ onFlowSelect={this.props.onFlowSelect}
onLocationSelect={this.props.onLocationSelect}
onSelect={this.props.onIssueSelect}
previousIssue={index > 0 ? this.props.issues[index - 1] : null}
scroll={this.handleScroll}
selected={issue.key === this.props.selected}
+ selectedFlowIndex={this.props.selectedFlowIndex}
selectedLocationIndex={this.props.selectedLocationIndex}
/>
))}
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssue-test.js.snap b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssue-test.js.snap
index 1d0309673f0..1413fcc82bf 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssue-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssue-test.js.snap
@@ -5,6 +5,7 @@ exports[`test should render 1`] = `
issue={Object {}}
onClick={[Function]}
selected={false}
+ selectedFlowIndex={null}
selectedLocationIndex={null} />
</div>
`;
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocationBadge-test.js.snap b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocationBadge-test.js.snap
index f131a618c5b..9eaefa3a503 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocationBadge-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocationBadge-test.js.snap
@@ -1,5 +1,6 @@
exports[`test should render 1`] = `
<Tooltip
+ mouseEnterDelay={0.5}
overlay="issue.this_issue_involves_x_code_locations.7"
placement="bottom">
<LocationIndex
diff --git a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocations-test.js.snap b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocations-test.js.snap
index 073f3d922c1..90378b33f25 100644
--- a/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocations-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/issues/conciseIssuesList/__tests__/__snapshots__/ConciseIssueLocations-test.js.snap
@@ -1,27 +1,36 @@
exports[`test should render one flow 1`] = `
<div
- className="pull-right">
+ className="concise-issue-locations pull-right">
<ConciseIssueLocationBadge
- count={3} />
+ count={3}
+ onClick={[Function]}
+ selected={false} />
</div>
`;
exports[`test should render secondary locations 1`] = `
<div
- className="pull-right">
+ className="concise-issue-locations pull-right">
<ConciseIssueLocationBadge
- count={3} />
+ count={3}
+ selected={true} />
</div>
`;
exports[`test should render several flows 1`] = `
<div
- className="pull-right">
+ className="concise-issue-locations pull-right">
<ConciseIssueLocationBadge
- count={3} />
+ count={3}
+ onClick={[Function]}
+ selected={false} />
<ConciseIssueLocationBadge
- count={2} />
+ count={2}
+ onClick={[Function]}
+ selected={false} />
<ConciseIssueLocationBadge
- count={3} />
+ count={3}
+ onClick={[Function]}
+ selected={false} />
</div>
`;
diff --git a/server/sonar-web/src/main/js/apps/issues/styles.css b/server/sonar-web/src/main/js/apps/issues/styles.css
index 6fbcb9b4e73..d035084daef 100644
--- a/server/sonar-web/src/main/js/apps/issues/styles.css
+++ b/server/sonar-web/src/main/js/apps/issues/styles.css
@@ -113,4 +113,20 @@
.concise-issue-box:not(.selected) .location-index {
background-color: #ccc;
+}
+
+.concise-issue-locations {
+ margin-right: -4px;
+ margin-bottom: -4px;
+}
+
+.concise-issue-locations .location-index {
+ margin-right: 4px;
+ margin-bottom: 4px;
+}
+
+.consice-issue-locations-navigator-location {
+ display: flex;
+ align-items: flex-start;
+ border: none;
} \ No newline at end of file
diff --git a/server/sonar-web/src/main/js/components/common/LocationIndex.js b/server/sonar-web/src/main/js/components/common/LocationIndex.js
index 03b74ee0c84..ecc4027b124 100644
--- a/server/sonar-web/src/main/js/components/common/LocationIndex.js
+++ b/server/sonar-web/src/main/js/components/common/LocationIndex.js
@@ -29,19 +29,13 @@ type Props = {
};
export default function LocationIndex(props: Props) {
- const clickAttributes = props.onClick
- ? {
- onClick: props.onClick,
- role: 'button',
- tabIndex: 0
- }
- : {};
+ const { children, onClick, selected, ...other } = props;
+ const clickAttributes = onClick ? { onClick, role: 'button', tabIndex: 0 } : {};
+ // put {...others} because Tooltip sets some event handlers
return (
- <div
- className={classNames('location-index', { selected: props.selected })}
- {...clickAttributes}>
- {props.children}
+ <div className={classNames('location-index', { selected })} {...clickAttributes} {...other}>
+ {children}
</div>
);
}
diff --git a/server/sonar-web/src/main/js/helpers/issues.js b/server/sonar-web/src/main/js/helpers/issues.js
index 804b410abf0..92603e52e17 100644
--- a/server/sonar-web/src/main/js/helpers/issues.js
+++ b/server/sonar-web/src/main/js/helpers/issues.js
@@ -108,6 +108,12 @@ const ensureTextRange = (issue: RawIssue) => {
: {};
};
+const reverseLocations = (locations: Array<*>) => {
+ const x = [...locations];
+ x.reverse();
+ return x;
+};
+
const splitFlows = (
issue: RawIssue
// $FlowFixMe textRange is not null
@@ -121,7 +127,7 @@ const splitFlows = (
return onlySecondaryLocations
? { secondaryLocations: flatten(parsedFlows), flows: [] }
- : { secondaryLocations: [], flows: parsedFlows };
+ : { secondaryLocations: [], flows: parsedFlows.map(reverseLocations) };
};
export const parseIssueFromResponse = (