aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-07-07 13:00:07 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-07-13 14:34:17 +0200
commite74ceaafe5549e07cc8ab52c7fb39945a6c3ed83 (patch)
treec85dc539aa00b775bf26128dbe086ca12b82daa5
parent41c087b7e17d18b72d01e948c89b0256475e505a (diff)
downloadsonarqube-e74ceaafe5549e07cc8ab52c7fb39945a6c3ed83.tar.gz
sonarqube-e74ceaafe5549e07cc8ab52c7fb39945a6c3ed83.zip
SONAR-9403 Remove history graphs from the measures page and redirect to project activity custom graph
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js4
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js171
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js38
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/routes.js13
-rw-r--r--tests/src/test/java/org/sonarqube/tests/measure/ProjectMeasuresPageTest.java20
5 files changed, 28 insertions, 218 deletions
diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js
index adaada9f517..f2dad990a91 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js
+++ b/server/sonar-web/src/main/js/apps/component-measures/details/MeasureDetailsHeader.js
@@ -45,8 +45,8 @@ export default function MeasureDetailsHeader({
{getLocalizedMetricName(metric)}
{!isDiff &&
<Link
- to={getComponentMeasureHistory(component.key, metric.key)}
- className="spacer-left button button-small button-compact">
+ className="js-show-history spacer-left button button-small button-compact"
+ to={getComponentMeasureHistory(component.key, metric.key)}>
<HistoryIcon />
</Link>}
</h2>
diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js
deleted file mode 100644
index 7cbf786922d..00000000000
--- a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistory.js
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { sortBy } from 'lodash';
-import moment from 'moment';
-import React from 'react';
-import Spinner from './../../components/Spinner';
-import Timeline from '../../../../components/charts/Timeline';
-import { getTimeMachineData } from '../../../../api/time-machine';
-import { getProjectActivity } from '../../../../api/projectActivity';
-import { formatMeasure, getShortType } from '../../../../helpers/measures';
-import { translate } from '../../../../helpers/l10n';
-
-const HEIGHT = 500;
-
-export default class MeasureHistory extends React.PureComponent {
- state = {
- components: [],
- selected: null,
- fetching: true
- };
-
- componentDidMount() {
- this.mounted = true;
- this.fetchHistory();
- }
-
- componentDidUpdate(nextProps) {
- if (nextProps.metric !== this.props.metric) {
- this.fetchHistory();
- }
- }
-
- componentWillUnmount() {
- this.mounted = false;
- }
-
- fetchHistory() {
- const { metric } = this.props;
-
- Promise.all([this.fetchTimeMachineData(metric.key), this.fetchEvents()]).then(responses => {
- if (this.mounted) {
- this.setState({
- snapshots: responses[0],
- events: responses[1],
- fetching: false
- });
- }
- });
- }
-
- fetchTimeMachineData(currentMetric, comparisonMetric) {
- const metricsToRequest = [currentMetric];
-
- if (comparisonMetric) {
- metricsToRequest.push(comparisonMetric);
- }
-
- return getTimeMachineData(this.props.component.key, metricsToRequest).then(r => {
- if (r.measures.length === 0) {
- return [];
- }
- return r.measures[0].history.filter(analysis => analysis.value != null).map(analysis => ({
- date: moment(analysis.date).toDate(),
- value: analysis.value
- }));
- });
- }
-
- fetchEvents() {
- if (this.props.component.qualifier !== 'TRK') {
- return Promise.resolve([]);
- }
-
- return getProjectActivity({
- project: this.props.component.key,
- category: 'VERSION'
- }).then(({ analyses }) => {
- const events = analyses.map(analysis => {
- const version = analysis.events.find(event => event.category === 'VERSION');
- return { version: version.name, date: moment(analysis.date).toDate() };
- });
-
- return sortBy(events, 'date');
- });
- }
-
- renderLineChart(snapshots, metric) {
- if (!metric) {
- return null;
- }
-
- if (snapshots.length < 2) {
- return this.renderWhenNoHistoricalData();
- }
-
- const data = snapshots.map(snapshot => {
- return {
- x: snapshot.date,
- y: metric.type === 'LEVEL' ? snapshot.value : Number(snapshot.value)
- };
- });
-
- const formatValue = value => formatMeasure(value, metric.type);
- const formatYTick = tick => formatMeasure(tick, getShortType(metric.type));
-
- return (
- <div style={{ height: HEIGHT }}>
- <Timeline
- basisCurve={false}
- key={metric.key}
- data={data}
- metricType={metric.type}
- events={this.state.events}
- height={HEIGHT}
- interpolate="linear"
- formatValue={formatValue}
- formatYTick={formatYTick}
- leakPeriodDate={this.props.leakPeriodDate}
- padding={[25, 25, 25, 60]}
- />
- </div>
- );
- }
-
- render() {
- const { fetching, snapshots } = this.state;
-
- if (fetching) {
- return (
- <div className="measure-details-history">
- <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}>
- <Spinner />
- </div>
- </div>
- );
- }
-
- if (!snapshots || snapshots.length < 2) {
- return (
- <div className="measure-details-history">
- <div className="note text-center" style={{ lineHeight: `${HEIGHT}px` }}>
- {translate('component_measures.no_history')}
- </div>
- </div>
- );
- }
-
- return (
- <div className="measure-details-history">
- {this.renderLineChart(this.state.snapshots, this.props.metric)}
- </div>
- );
- }
-}
diff --git a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js b/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js
deleted file mode 100644
index 72fe0385a2c..00000000000
--- a/server/sonar-web/src/main/js/apps/component-measures/details/history/MeasureHistoryContainer.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2017 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-import { connect } from 'react-redux';
-import MeasureHistory from './MeasureHistory';
-import {
- getMeasuresAppDetailsMetric,
- getMeasuresAppComponent
-} from '../../../../store/rootReducer';
-
-const mapStateToProps = state => {
- return {
- component: getMeasuresAppComponent(state),
- metric: getMeasuresAppDetailsMetric(state)
- };
-};
-
-const mapDispatchToProps = () => {
- return {};
-};
-
-export default connect(mapStateToProps, mapDispatchToProps)(MeasureHistory);
diff --git a/server/sonar-web/src/main/js/apps/component-measures/routes.js b/server/sonar-web/src/main/js/apps/component-measures/routes.js
index a416e181a22..c4b1fb5162d 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/routes.js
+++ b/server/sonar-web/src/main/js/apps/component-measures/routes.js
@@ -82,10 +82,15 @@ const routes = [
},
{
path: 'history',
- getComponent(_, callback) {
- require.ensure([], require =>
- callback(null, require('./details/history/MeasureHistoryContainer').default)
- );
+ onEnter(nextState, replace) {
+ replace({
+ pathname: '/project/activity',
+ query: {
+ id: nextState.location.query.id,
+ graph: 'custom',
+ custom_metrics: nextState.params.metricKey
+ }
+ });
}
},
{
diff --git a/tests/src/test/java/org/sonarqube/tests/measure/ProjectMeasuresPageTest.java b/tests/src/test/java/org/sonarqube/tests/measure/ProjectMeasuresPageTest.java
index 46ee9aafd11..e0acee4fc3c 100644
--- a/tests/src/test/java/org/sonarqube/tests/measure/ProjectMeasuresPageTest.java
+++ b/tests/src/test/java/org/sonarqube/tests/measure/ProjectMeasuresPageTest.java
@@ -30,6 +30,8 @@ import org.sonarqube.pageobjects.Navigation;
import static com.codeborne.selenide.Condition.visible;
import static com.codeborne.selenide.Selenide.$;
import static com.codeborne.selenide.Selenide.$$;
+import static com.codeborne.selenide.WebDriverRunner.url;
+import static org.assertj.core.api.Assertions.assertThat;
import static util.ItUtils.projectDir;
import static util.selenium.Selenese.runSelenese;
@@ -70,11 +72,23 @@ public class ProjectMeasuresPageTest {
}
@Test
- public void should_show_history() {
+ public void should_redirect_history_to_project_activity() {
Navigation nav = Navigation.create(orchestrator);
nav.open("/component_measures/metric/reliability_rating/history?id=project-measures-page-test-project");
- $(".line-chart").shouldBe(visible);
- $$(".line-chart-tick-x").shouldHaveSize(5);
+ assertThat(url())
+ .contains("/project/activity")
+ .contains("id=project-measures-page-test-project")
+ .contains("graph=custom")
+ .contains("custom_metrics=reliability_rating");
+ }
+
+
+ @Test
+ public void should_show_link_to_history() {
+ Navigation nav = Navigation.create(orchestrator);
+ nav.open("/component_measures/metric/reliability_rating/list?id=project-measures-page-test-project");
+ $(".js-show-history").shouldBe(visible).click();
+ $("#project-activity").shouldBe(visible);
}
}