aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-07-06 15:28:53 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-07-13 14:34:17 +0200
commit70f4f8576349995eda926a82abc6d453e61b32eb (patch)
treec59d26c3600602de93235b47c4a91c795d6109a8
parentcb00b707c047dd648e720b491cd7a7181f9c8b48 (diff)
downloadsonarqube-70f4f8576349995eda926a82abc6d453e61b32eb.tar.gz
sonarqube-70f4f8576349995eda926a82abc6d453e61b32eb.zip
SONAR-9403 Allow to remove a metric fromt the custom graph
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/GraphsHistory.js16
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendCustom.js48
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.js66
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendStatic.js19
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityApp.js1
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js23
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphsHeader.js13
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsHistory-test.js2
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendCustom-test.js39
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendItem-test.js40
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js1
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendCustom-test.js.snap38
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.js.snap32
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendStatic-test.js.snap24
-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.snap5
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddGraphMetric.js5
-rw-r--r--server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css6
18 files changed, 330 insertions, 49 deletions
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsHistory.js b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsHistory.js
index 36ac11b372e..130bf03e018 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsHistory.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsHistory.js
@@ -23,11 +23,12 @@ import { sortBy } from 'lodash';
import { AutoSizer } from 'react-virtualized';
import AdvancedTimeline from '../../../components/charts/AdvancedTimeline';
import GraphsTooltips from './GraphsTooltips';
+import GraphsLegendCustom from './GraphsLegendCustom';
import GraphsLegendStatic from './GraphsLegendStatic';
import { formatMeasure, getShortType } from '../../../helpers/measures';
import { EVENT_TYPES, hasHistoryData, isCustomGraph } from '../utils';
import { translate } from '../../../helpers/l10n';
-import type { Analysis, MeasureHistory } from '../types';
+import type { Analysis, MeasureHistory, Metric } from '../types';
import type { Serie } from '../../../components/charts/AdvancedTimeline';
type Props = {
@@ -39,7 +40,9 @@ type Props = {
leakPeriodDate: Date,
loading: boolean,
measuresHistory: Array<MeasureHistory>,
+ metrics: Array<Metric>,
metricsType: string,
+ removeCustomMetric: (metric: string) => void,
selectedDate?: ?Date => void,
series: Array<Serie>,
updateGraphZoom: (from: ?Date, to: ?Date) => void,
@@ -105,6 +108,7 @@ export default class GraphsHistory extends React.PureComponent {
render() {
const { loading } = this.props;
const { graph, series } = this.props;
+ const isCustom = isCustomGraph(graph);
if (loading) {
return (
@@ -121,7 +125,7 @@ export default class GraphsHistory extends React.PureComponent {
<div className="project-activity-graph-container">
<div className="note text-center">
{translate(
- isCustomGraph(this.props.graph)
+ isCustom
? 'project_activity.graphs.custom.no_history'
: 'component_measures.no_history'
)}
@@ -133,7 +137,13 @@ export default class GraphsHistory extends React.PureComponent {
const { selectedDate, tooltipIdx, tooltipXPos } = this.state;
return (
<div className="project-activity-graph-container">
- <GraphsLegendStatic series={series} />
+ {isCustom
+ ? <GraphsLegendCustom
+ series={series}
+ metrics={this.props.metrics}
+ removeMetric={this.props.removeCustomMetric}
+ />
+ : <GraphsLegendStatic series={series} />}
<div className="project-activity-graph">
<AutoSizer>
{({ height, width }) => (
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendCustom.js b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendCustom.js
new file mode 100644
index 00000000000..e0236cb4e2f
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendCustom.js
@@ -0,0 +1,48 @@
+/*
+ * 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 React from 'react';
+import GraphsLegendItem from './GraphsLegendItem';
+import type { Metric } from '../types';
+
+type Props = {
+ metrics: Array<Metric>,
+ removeMetric: string => void,
+ series: Array<{ name: string, translatedName: string, style: string }>
+};
+
+export default function GraphsLegendCustom({ metrics, removeMetric, series }: Props) {
+ return (
+ <div className="project-activity-graph-legends">
+ {series.map(serie => {
+ const metric = metrics.find(metric => metric.key === serie.name);
+ return (
+ <span className="spacer-left spacer-right" key={serie.name}>
+ <GraphsLegendItem
+ metric={serie.name}
+ name={metric && metric.custom ? metric.name : serie.translatedName}
+ style={serie.style}
+ removeMetric={removeMetric}
+ />
+ </span>
+ );
+ })}
+ </div>
+ );
+}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.js b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.js
new file mode 100644
index 00000000000..79d294505c0
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendItem.js
@@ -0,0 +1,66 @@
+/*
+ * 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 React from 'react';
+import classNames from 'classnames';
+import CloseIcon from '../../../components/icons-components/CloseIcon';
+import ChartLegendIcon from '../../../components/icons-components/ChartLegendIcon';
+
+type Props = {
+ className?: string,
+ metric: string,
+ name: string,
+ style: string,
+ removeMetric?: string => void
+};
+
+export default class GraphsLegendItem extends React.PureComponent {
+ props: Props;
+
+ handleClick = (e: Event) => {
+ e.preventDefault();
+ this.props.removeMetric(this.props.metric);
+ };
+
+ render() {
+ const isActionable = this.props.removeMetric != null;
+ const legendClass = classNames(
+ {
+ 'project-activity-graph-legend-actionable': isActionable
+ },
+ this.props.className
+ );
+
+ return (
+ <span className={legendClass}>
+ <ChartLegendIcon
+ className={classNames(
+ 'spacer-right line-chart-legend',
+ 'line-chart-legend-' + this.props.style
+ )}
+ />
+ {this.props.name}
+ {isActionable &&
+ <a className="spacer-left button-clean text-text-top" href="#" onClick={this.handleClick}>
+ <CloseIcon className="text-danger" />
+ </a>}
+ </span>
+ );
+ }
+}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendStatic.js b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendStatic.js
index 7dffdf75321..123bc9548b7 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendStatic.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/GraphsLegendStatic.js
@@ -18,8 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
-import classNames from 'classnames';
-import ChartLegendIcon from '../../../components/icons-components/ChartLegendIcon';
+import GraphsLegendItem from './GraphsLegendItem';
type Props = {
series: Array<{ name: string, translatedName: string, style: string }>
@@ -29,15 +28,13 @@ export default function GraphsLegendStatic({ series }: Props) {
return (
<div className="project-activity-graph-legends">
{series.map(serie => (
- <span className="big-spacer-left big-spacer-right" key={serie.name}>
- <ChartLegendIcon
- className={classNames(
- 'spacer-right line-chart-legend',
- 'line-chart-legend-' + serie.style
- )}
- />
- {serie.translatedName}
- </span>
+ <GraphsLegendItem
+ className="big-spacer-left big-spacer-right"
+ key={serie.name}
+ metric={serie.name}
+ name={serie.translatedName}
+ style={serie.style}
+ />
))}
</div>
);
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 02a1f1b5eb3..d982bc837cc 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
@@ -127,7 +127,6 @@ export default class ProjectActivityApp extends React.PureComponent {
measuresHistory={measuresHistory}
metrics={this.props.metrics}
metricsType={this.getMetricType()}
- project={this.props.project.key}
query={query}
updateQuery={this.props.updateQuery}
/>
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js
index 0b86b71bdc5..13d42349be3 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphs.js
@@ -40,7 +40,6 @@ type Props = {
measuresHistory: Array<MeasureHistory>,
metrics: Array<Metric>,
metricsType: string,
- project: string,
query: Query,
updateQuery: RawQuery => void
};
@@ -108,7 +107,15 @@ export default class ProjectActivityGraphs extends React.PureComponent {
}
};
- updateSelectedDate = (selectedDate: ?Date) => this.props.updateQuery({ selectedDate });
+ addCustomMetric = (metric: string) =>
+ this.props.updateQuery({ customMetrics: [...this.props.query.customMetrics, metric] });
+
+ removeCustomMetric = (removedMetric: string) =>
+ this.props.updateQuery({
+ customMetrics: this.props.query.customMetrics.filter(metric => metric !== removedMetric)
+ });
+
+ updateGraph = (graph: string) => this.props.updateQuery({ graph });
updateGraphZoom = (graphStartDate: ?Date, graphEndDate: ?Date) => {
if (graphEndDate != null && graphStartDate != null) {
@@ -123,6 +130,8 @@ export default class ProjectActivityGraphs extends React.PureComponent {
this.updateQueryDateRange([graphStartDate, graphEndDate]);
};
+ updateSelectedDate = (selectedDate: ?Date) => this.props.updateQuery({ selectedDate });
+
updateQueryDateRange = (dates: Array<?Date>) => {
if (dates[0] == null || dates[1] == null) {
this.props.updateQuery({ from: dates[0], to: dates[1] });
@@ -133,15 +142,16 @@ export default class ProjectActivityGraphs extends React.PureComponent {
};
render() {
- const { leakPeriodDate, loading, metricsType, query } = this.props;
+ const { leakPeriodDate, loading, metrics, metricsType, query } = this.props;
const { series } = this.state;
return (
<div className="project-activity-layout-page-main-inner boxed-group boxed-group-inner">
<ProjectActivityGraphsHeader
+ addCustomMetric={this.addCustomMetric}
graph={query.graph}
- metrics={this.props.metrics}
+ metrics={metrics}
selectedMetrics={this.props.query.customMetrics}
- updateQuery={this.props.updateQuery}
+ updateGraph={this.updateGraph}
/>
<GraphsHistory
analyses={this.props.analyses}
@@ -152,8 +162,9 @@ export default class ProjectActivityGraphs extends React.PureComponent {
leakPeriodDate={leakPeriodDate}
loading={loading}
measuresHistory={this.props.measuresHistory}
+ metrics={metrics}
metricsType={metricsType}
- project={this.props.project}
+ removeCustomMetric={this.removeCustomMetric}
selectedDate={this.props.query.selectedDate}
series={series}
updateGraphZoom={this.updateGraphZoom}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphsHeader.js b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphsHeader.js
index 194af091b69..007b04f4d52 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphsHeader.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/ProjectActivityGraphsHeader.js
@@ -24,13 +24,13 @@ import AddGraphMetric from './forms/AddGraphMetric';
import { isCustomGraph, GRAPH_TYPES } from '../utils';
import { translate } from '../../../helpers/l10n';
import type { Metric } from '../types';
-import type { RawQuery } from '../../../helpers/query';
type Props = {
+ addCustomMetric: string => void,
graph: string,
metrics: Array<Metric>,
selectedMetrics: Array<string>,
- updateQuery: RawQuery => void
+ updateGraph: string => void
};
export default class ProjectActivityGraphsHeader extends React.PureComponent {
@@ -38,15 +38,10 @@ export default class ProjectActivityGraphsHeader extends React.PureComponent {
handleGraphChange = (option: { value: string }) => {
if (option.value !== this.props.graph) {
- this.props.updateQuery({ graph: option.value });
+ this.props.updateGraph(option.value);
}
};
- handleAddMetric = (metric: string) => {
- const selectedMetrics = [...this.props.selectedMetrics, metric];
- this.props.updateQuery({ customMetrics: selectedMetrics });
- };
-
render() {
const selectOptions = GRAPH_TYPES.map(graph => ({
label: translate('project_activity.graphs', graph),
@@ -65,7 +60,7 @@ export default class ProjectActivityGraphsHeader extends React.PureComponent {
/>
{isCustomGraph(this.props.graph) &&
<AddGraphMetric
- addMetric={this.handleAddMetric}
+ addMetric={this.props.addCustomMetric}
className="spacer-left"
metrics={this.props.metrics}
selectedMetrics={this.props.selectedMetrics}
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsHistory-test.js b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsHistory-test.js
index 94d9d326340..f13577ae571 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsHistory-test.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsHistory-test.js
@@ -87,7 +87,9 @@ const DEFAULT_PROPS = {
leakPeriodDate: '2017-05-16T13:50:02+0200',
loading: false,
measuresHistory: [],
+ metrics: [],
metricsType: 'INT',
+ removeCustomMetric: () => {},
selectedDate: null,
series: SERIES,
updateGraphZoom: () => {},
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendCustom-test.js b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendCustom-test.js
new file mode 100644
index 00000000000..9b785f2213b
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendCustom-test.js
@@ -0,0 +1,39 @@
+/*
+ * 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 React from 'react';
+import { shallow } from 'enzyme';
+import GraphsLegendCustom from '../GraphsLegendCustom';
+
+const SERIES = [
+ { name: 'bugs', translatedName: 'Bugs', style: '2', data: [] },
+ { name: 'my_metric', translatedName: 'metric.my_metric.name', style: '1', data: [] },
+ { name: 'foo', translatedName: 'Foo', style: '0', data: [] }
+];
+
+const METRICS = [
+ { key: 'bugs', name: 'Bugs' },
+ { key: 'my_metric', name: 'My Metric', custom: true }
+];
+
+it('should render correctly the list of series', () => {
+ expect(
+ shallow(<GraphsLegendCustom metrics={METRICS} removeMetric={() => {}} series={SERIES} />)
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendItem-test.js b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendItem-test.js
new file mode 100644
index 00000000000..a000a1dec04
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/GraphsLegendItem-test.js
@@ -0,0 +1,40 @@
+/*
+ * 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 React from 'react';
+import { shallow } from 'enzyme';
+import GraphsLegendItem from '../GraphsLegendItem';
+
+it('should render correctly a legend', () => {
+ expect(shallow(<GraphsLegendItem metric="bugs" name="Bugs" style="2" />)).toMatchSnapshot();
+});
+
+it('should render correctly an actionable legend', () => {
+ expect(
+ shallow(
+ <GraphsLegendItem
+ className="myclass"
+ metric="foo"
+ name="Foo"
+ style="1"
+ removeMetric={() => {}}
+ />
+ )
+ ).toMatchSnapshot();
+});
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js
index 2b27845d57c..07930d40463 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityGraphs-test.js
@@ -71,7 +71,6 @@ const DEFAULT_PROPS = {
}
],
metricsType: 'INT',
- project: 'org.sonarsource.sonarqube:sonarqube',
query: { category: '', graph: 'overview', project: 'org.sonarsource.sonarqube:sonarqube' },
updateQuery: () => {}
};
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendCustom-test.js.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendCustom-test.js.snap
new file mode 100644
index 00000000000..b19b8e8e654
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendCustom-test.js.snap
@@ -0,0 +1,38 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly the list of series 1`] = `
+<div
+ className="project-activity-graph-legends"
+>
+ <span
+ className="spacer-left spacer-right"
+ >
+ <GraphsLegendItem
+ metric="bugs"
+ name="Bugs"
+ removeMetric={[Function]}
+ style="2"
+ />
+ </span>
+ <span
+ className="spacer-left spacer-right"
+ >
+ <GraphsLegendItem
+ metric="my_metric"
+ name="My Metric"
+ removeMetric={[Function]}
+ style="1"
+ />
+ </span>
+ <span
+ className="spacer-left spacer-right"
+ >
+ <GraphsLegendItem
+ metric="foo"
+ name="Foo"
+ removeMetric={[Function]}
+ style="0"
+ />
+ </span>
+</div>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.js.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.js.snap
new file mode 100644
index 00000000000..84dc737ae03
--- /dev/null
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendItem-test.js.snap
@@ -0,0 +1,32 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`should render correctly a legend 1`] = `
+<span
+ className=""
+>
+ <ChartLegendIcon
+ className="spacer-right line-chart-legend line-chart-legend-2"
+ />
+ Bugs
+</span>
+`;
+
+exports[`should render correctly an actionable legend 1`] = `
+<span
+ className="project-activity-graph-legend-actionable myclass"
+>
+ <ChartLegendIcon
+ className="spacer-right line-chart-legend line-chart-legend-1"
+ />
+ Foo
+ <a
+ className="spacer-left button-clean text-text-top"
+ href="#"
+ onClick={[Function]}
+ >
+ <CloseIcon
+ className="text-danger"
+ />
+ </a>
+</span>
+`;
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendStatic-test.js.snap b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendStatic-test.js.snap
index 1fd564f69ef..97610c6365f 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendStatic-test.js.snap
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/__snapshots__/GraphsLegendStatic-test.js.snap
@@ -4,21 +4,17 @@ exports[`should render correctly the list of series 1`] = `
<div
className="project-activity-graph-legends"
>
- <span
+ <GraphsLegendItem
className="big-spacer-left big-spacer-right"
- >
- <ChartLegendIcon
- className="spacer-right line-chart-legend line-chart-legend-2"
- />
- Bugs
- </span>
- <span
+ metric="bugs"
+ name="Bugs"
+ style="2"
+ />
+ <GraphsLegendItem
className="big-spacer-left big-spacer-right"
- >
- <ChartLegendIcon
- className="spacer-right line-chart-legend line-chart-legend-1"
- />
- Code Smells
- </span>
+ metric="code_smells"
+ name="Code Smells"
+ style="1"
+ />
</div>
`;
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 1943a2f48ac..7fa450f12c8 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
@@ -189,7 +189,6 @@ exports[`should render correctly 1`] = `
]
}
metricsType="INT"
- project="org.sonarsource.sonarqube:sonarqube"
query={
Object {
"category": "",
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 3c46221619f..a32cd28f590 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
@@ -5,8 +5,9 @@ exports[`should render correctly the graph and legends 1`] = `
className="project-activity-layout-page-main-inner boxed-group boxed-group-inner"
>
<ProjectActivityGraphsHeader
+ addCustomMetric={[Function]}
graph="overview"
- updateQuery={[Function]}
+ updateGraph={[Function]}
/>
<GraphsHistory
analyses={
@@ -73,7 +74,7 @@ exports[`should render correctly the graph and legends 1`] = `
]
}
metricsType="INT"
- project="org.sonarsource.sonarqube:sonarqube"
+ removeCustomMetric={[Function]}
series={
Array [
Object {
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddGraphMetric.js b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddGraphMetric.js
index a7193b62093..d0a435a97ce 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddGraphMetric.js
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/forms/AddGraphMetric.js
@@ -138,7 +138,10 @@ export default class AddGraphMetric extends React.PureComponent {
render() {
return (
- <button className={this.props.className} onClick={this.openForm}>
+ <button
+ className={this.props.className}
+ onClick={this.openForm}
+ disabled={this.props.selectedMetrics.length >= 3}>
{translate('project_activity.graphs.custom.add')}
{this.state.open && this.renderModal()}
</button>
diff --git a/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css b/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css
index 35b51275992..cc0b6d1bd7a 100644
--- a/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css
+++ b/server/sonar-web/src/main/js/apps/projectActivity/components/projectActivity.css
@@ -62,6 +62,12 @@
text-align: center;
}
+.project-activity-graph-legend-actionable {
+ padding: 4px 12px;
+ border: 1px solid #e6e6e6;
+ border-radius: 12px;
+}
+
.project-activity-graph-tooltip {
padding: 8px;
pointer-events: none;