diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-06-28 10:48:55 +0200 |
---|---|---|
committer | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-07-04 14:15:34 +0200 |
commit | 8a457c9d5d80c5e618fd9c79a366cbfc2746e8f2 (patch) | |
tree | d31df63c2b59bef8dd68a07657312dac0097b3b6 /server/sonar-web/src/main/js/apps | |
parent | 3a2e4d3af7939b8017379527e0213b113a6d52e1 (diff) | |
download | sonarqube-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')
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; }, []); |