aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src/main/js/apps
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-06-28 10:48:55 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-07-04 14:15:34 +0200
commit8a457c9d5d80c5e618fd9c79a366cbfc2746e8f2 (patch)
treed31df63c2b59bef8dd68a07657312dac0097b3b6 /server/sonar-web/src/main/js/apps
parent3a2e4d3af7939b8017379527e0213b113a6d52e1 (diff)
downloadsonarqube-8a457c9d5d80c5e618fd9c79a366cbfc2746e8f2.tar.gz
sonarqube-8a457c9d5d80c5e618fd9c79a366cbfc2746e8f2.zip
Fix project history data loading bug when a graph is saved in localstorage
Diffstat (limited to 'server/sonar-web/src/main/js/apps')
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js10
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js8
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js7
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js57
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-test.js2
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.js.snap1
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap10
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/utils.js6
8 files changed, 62 insertions, 39 deletions
diff --git a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js
index b9071b92d74..2be253ef9f6 100644
--- a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js
+++ b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.js
@@ -19,13 +19,15 @@
*/
// @flow
import React from 'react';
+import { uniq } from 'lodash';
import moment from 'moment';
import QualityGate from '../qualityGate/QualityGate';
import BugsAndVulnerabilities from '../main/BugsAndVulnerabilities';
import CodeSmells from '../main/CodeSmells';
import Coverage from '../main/Coverage';
import Duplications from '../main/Duplications';
-import Meta from './../meta/Meta';
+import Meta from '../meta/Meta';
+import throwGlobalError from '../../../app/utils/throwGlobalError';
import { getMeasuresAndMeta } from '../../../api/measures';
import { getAllTimeMachineData } from '../../../api/time-machine';
import { enhanceMeasuresWithMetrics } from '../../../helpers/measures';
@@ -95,11 +97,11 @@ export default class OverviewApp extends React.PureComponent {
periods: r.periods
});
}
- });
+ }, throwGlobalError);
}
loadHistory(component: Component) {
- const metrics = HISTORY_METRICS_LIST.concat(GRAPHS_METRICS[getGraph()]);
+ const metrics = uniq(HISTORY_METRICS_LIST.concat(GRAPHS_METRICS[getGraph()]));
return getAllTimeMachineData(component.key, metrics).then(r => {
if (this.mounted) {
const history: History = {};
@@ -113,7 +115,7 @@ export default class OverviewApp extends React.PureComponent {
const historyStartDate = history[HISTORY_METRICS_LIST[0]][0].date;
this.setState({ history, historyStartDate });
}
- });
+ }, throwGlobalError);
}
renderLoading() {
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js
index d0655faec68..368ecf5abe9 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAnalysesList.js
@@ -21,6 +21,7 @@
import React from 'react';
import classNames from 'classnames';
import moment from 'moment';
+import { throttle } from 'lodash';
import ProjectActivityAnalysis from './ProjectActivityAnalysis';
import FormattedDate from '../../../components/ui/FormattedDate';
import { translate } from '../../../helpers/l10n';
@@ -45,6 +46,11 @@ export default class ProjectActivityAnalysesList extends React.PureComponent {
badges: HTMLCollection<HTMLElement>;
props: Props;
+ constructor(props: Props) {
+ super(props);
+ this.handleScroll = throttle(this.handleScroll, 20);
+ }
+
componentDidMount() {
this.badges = document.getElementsByClassName('project-activity-version-badge');
}
@@ -107,7 +113,7 @@ export default class ProjectActivityAnalysesList extends React.PureComponent {
onScroll={this.handleScroll}
ref={element => (this.scrollContainer = element)}>
{byVersionByDay.map((version, idx) => (
- <li key={idx + version.version}>
+ <li key={version.key || 'noversion'}>
{version.version &&
<div className={classNames('project-activity-version-badge', { first: idx === 0 })}>
<span className="badge">
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js
index 1904f8d975d..9b4f2a595dd 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js
@@ -37,6 +37,7 @@ type Props = {
changeEvent: (event: string, name: string) => Promise<*>,
deleteAnalysis: (analysis: string) => Promise<*>,
deleteEvent: (analysis: string, event: string) => Promise<*>,
+ graphLoading: boolean,
loading: boolean,
project: { configuration?: { showHistory: boolean }, key: string, leakPeriodDate: string },
metrics: Array<Metric>,
@@ -87,7 +88,7 @@ export default class ProjectActivityApp extends React.PureComponent {
};
render() {
- const { loading, measuresHistory, query } = this.props;
+ const { measuresHistory, query } = this.props;
const { filteredAnalyses } = this.state;
const { configuration } = this.props.project;
const canAdmin = configuration ? configuration.showHistory : false;
@@ -109,14 +110,14 @@ export default class ProjectActivityApp extends React.PureComponent {
changeEvent={this.props.changeEvent}
deleteAnalysis={this.props.deleteAnalysis}
deleteEvent={this.props.deleteEvent}
- loading={loading}
+ loading={this.props.loading}
/>
</div>
<div className="project-activity-layout-page-main">
<ProjectActivityGraphs
analyses={filteredAnalyses}
leakPeriodDate={moment(this.props.project.leakPeriodDate).toDate()}
- loading={loading}
+ loading={this.props.graphLoading}
measuresHistory={measuresHistory}
metricsType={this.getMetricType()}
project={this.props.project.key}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js
index e7a4e2505ef..774f1165eae 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityAppContainer.js
@@ -86,9 +86,9 @@ class ProjectActivityAppContainer extends React.PureComponent {
elem && elem.classList.add('dashboard-page');
}
- componentDidUpdate(prevProps: Props) {
- if (prevProps.location.query !== this.props.location.query) {
- const query = parseQuery(this.props.location.query);
+ componentWillReceiveProps(nextProps: Props) {
+ if (nextProps.location.query !== this.props.location.query) {
+ const query = parseQuery(nextProps.location.query);
if (query.graph !== this.state.query.graph) {
this.updateGraphData(query.graph);
}
@@ -157,8 +157,8 @@ class ProjectActivityAppContainer extends React.PureComponent {
);
};
- fetchMeasuresHistory = (metrics: Array<string>): Promise<Array<MeasureHistory>> =>
- getAllTimeMachineData(this.props.project.key, metrics).then(
+ fetchMeasuresHistory = (metrics: Array<string>): Promise<Array<MeasureHistory>> => {
+ return getAllTimeMachineData(this.props.project.key, metrics).then(
({ measures }) =>
measures.map(measure => ({
metric: measure.metric,
@@ -169,6 +169,7 @@ class ProjectActivityAppContainer extends React.PureComponent {
})),
throwGlobalError
);
+ };
fetchMetrics = (): Promise<Array<Metric>> => getMetrics().catch(throwGlobalError);
@@ -197,31 +198,41 @@ class ProjectActivityAppContainer extends React.PureComponent {
firstLoadData() {
const { query } = this.state;
const graphMetrics = GRAPHS_METRICS[query.graph];
+ const ignoreHistory = this.shouldRedirect();
Promise.all([
this.fetchActivity(query.project, 1, 100, serializeQuery(query)),
this.fetchMetrics(),
- this.fetchMeasuresHistory(graphMetrics)
+ ignoreHistory ? Promise.resolve() : this.fetchMeasuresHistory(graphMetrics)
]).then(response => {
if (this.mounted) {
- this.setState({
- analyses: response[0].analyses,
- analysesLoading: true,
- graphLoading: false,
- loading: false,
- metrics: response[1],
- measuresHistory: response[2],
- paging: response[0].paging
- });
-
- this.loadAllActivities(query.project).then(({ analyses, paging }) => {
- if (this.mounted) {
+ setTimeout(() => {
+ const newState = {
+ analyses: response[0].analyses,
+ analysesLoading: true,
+ loading: false,
+ metrics: response[1],
+ paging: response[0].paging
+ };
+ if (ignoreHistory) {
+ this.setState(newState);
+ } else {
this.setState({
- analyses,
- analysesLoading: false,
- paging
+ ...newState,
+ graphLoading: false,
+ measuresHistory: response[2]
});
}
- });
+
+ this.loadAllActivities(query.project).then(({ analyses, paging }) => {
+ if (this.mounted) {
+ this.setState({
+ analyses,
+ analysesLoading: false,
+ paging
+ });
+ }
+ });
+ }, 1000);
}
});
}
@@ -273,7 +284,7 @@ class ProjectActivityAppContainer extends React.PureComponent {
changeEvent={this.changeEvent}
deleteAnalysis={this.deleteAnalysis}
deleteEvent={this.deleteEvent}
- graphLoading={this.state.graphLoading}
+ graphLoading={this.state.loading || this.state.graphLoading}
loading={this.state.loading}
metrics={this.state.metrics}
measuresHistory={this.state.measuresHistory}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-test.js b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-test.js
index e6122763349..22f85b2a28f 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-test.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-test.js
@@ -60,9 +60,11 @@ const DEFAULT_PROPS = {
addCustomEvent: () => {},
addVersion: () => {},
analyses: ANALYSES,
+ analysesLoading: false,
changeEvent: () => {},
deleteAnalysis: () => {},
deleteEvent: () => {},
+ graphLoading: false,
loading: false,
project: {
key: 'org.sonarsource.sonarqube:sonarqube',
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.js.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.js.snap
index c34ab47e81c..0f5a433fbfe 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityApp-test.js.snap
@@ -103,6 +103,7 @@ exports[`should render correctly 1`] = `
},
]
}
+ analysesLoading={false}
canAdmin={false}
changeEvent={[Function]}
className="boxed-group-inner"
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap
index 67899574868..920f463b1ea 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/ProjectActivityGraphs-test.js.snap
@@ -46,8 +46,8 @@ exports[`should render correctly the graph and legends 1`] = `
]
}
eventFilter=""
- graphEndDate={null}
- graphStartDate={null}
+ graphEndDate={2016-10-27T14:33:50.000Z}
+ graphStartDate={2016-10-26T10:17:29.000Z}
leakPeriodDate="2017-05-16T13:50:02+0200"
loading={false}
metricsType="INT"
@@ -79,8 +79,8 @@ exports[`should render correctly the graph and legends 1`] = `
updateGraphZoom={[Function]}
/>
<GraphsZoom
- graphEndDate={null}
- graphStartDate={null}
+ graphEndDate={2016-10-27T14:33:50.000Z}
+ graphStartDate={2016-10-26T10:17:29.000Z}
leakPeriodDate="2017-05-16T13:50:02+0200"
loading={false}
metricsType="INT"
@@ -115,8 +115,6 @@ exports[`should render correctly the graph and legends 1`] = `
exports[`should render correctly with filter history on dates 1`] = `
Object {
- "graphEndDate": null,
- "graphStartDate": "2016-10-27T12:21:15+0200",
"series": Array [
Object {
"data": Array [
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/utils.js b/server/sonar-web/src/main/js/apps/projectActivity/utils.js
index 2c0c3c818bc..7f5389028d1 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/utils.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/utils.js
@@ -99,11 +99,12 @@ export const getAnalysesByVersionByDay = (
analyses: Array<Analysis>
): Array<{
version: ?string,
+ key: ?string,
byDay: { [string]: Array<Analysis> }
}> =>
analyses.reduce((acc, analysis) => {
if (acc.length === 0) {
- acc.push({ version: undefined, byDay: {} });
+ acc.push({ version: undefined, key: undefined, byDay: {} });
}
const currentVersion = acc[acc.length - 1];
const day = moment(analysis.date).startOf('day').valueOf().toString();
@@ -122,7 +123,8 @@ export const getAnalysesByVersionByDay = (
const lastEvent = sortedEvents[sortedEvents.length - 1];
if (lastEvent && lastEvent.category === 'VERSION') {
currentVersion.version = lastEvent.name;
- acc.push({ version: undefined, byDay: {} });
+ currentVersion.key = lastEvent.key;
+ acc.push({ version: undefined, key: undefined, byDay: {} });
}
return acc;
}, []);