diff options
author | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-07-06 15:28:53 +0200 |
---|---|---|
committer | Grégoire Aubert <gregoire.aubert@sonarsource.com> | 2017-07-13 14:34:17 +0200 |
commit | 70f4f8576349995eda926a82abc6d453e61b32eb (patch) | |
tree | c59d26c3600602de93235b47c4a91c795d6109a8 | |
parent | cb00b707c047dd648e720b491cd7a7181f9c8b48 (diff) | |
download | sonarqube-70f4f8576349995eda926a82abc6d453e61b32eb.tar.gz sonarqube-70f4f8576349995eda926a82abc6d453e61b32eb.zip |
SONAR-9403 Allow to remove a metric fromt the custom graph
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; |