From aa0ced5bc4a11dc28a5f8e298b03e7011bcb62d3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gr=C3=A9goire=20Aubert?= Date: Thu, 22 Feb 2018 14:29:30 +0100 Subject: [PATCH] SONAR-10440 Remove useless tooltips on project overview measures --- ...end.js => ApplicationLeakPeriodLegend.tsx} | 40 ++++++-------- .../apps/overview/components/OverviewApp.tsx | 4 +- ...s => ApplicationLeakPeriodLegend-test.tsx} | 5 +- ...ApplicationLeakPeriodLegend-test.tsx.snap} | 0 ...bilities.js => BugsAndVulnerabilities.tsx} | 13 ++--- .../main/{CodeSmells.js => CodeSmells.tsx} | 34 ++++-------- .../main/{Coverage.js => Coverage.tsx} | 55 ++++++++----------- .../{Duplications.js => Duplications.tsx} | 38 +++++++------ .../main/js/apps/overview/main/enhance.tsx | 23 ++------ .../resources/org/sonar/l10n/core.properties | 2 - 10 files changed, 88 insertions(+), 126 deletions(-) rename server/sonar-web/src/main/js/apps/overview/components/{ApplicationLeakPeriodLegend.js => ApplicationLeakPeriodLegend.tsx} (78%) rename server/sonar-web/src/main/js/apps/overview/components/__tests__/{ApplicationLeakPeriodLegend-test.js => ApplicationLeakPeriodLegend-test.tsx} (95%) rename server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/{ApplicationLeakPeriodLegend-test.js.snap => ApplicationLeakPeriodLegend-test.tsx.snap} (100%) rename server/sonar-web/src/main/js/apps/overview/main/{BugsAndVulnerabilities.js => BugsAndVulnerabilities.tsx} (95%) rename server/sonar-web/src/main/js/apps/overview/main/{CodeSmells.js => CodeSmells.tsx} (84%) rename server/sonar-web/src/main/js/apps/overview/main/{Coverage.js => Coverage.tsx} (79%) rename server/sonar-web/src/main/js/apps/overview/main/{Duplications.js => Duplications.tsx} (87%) diff --git a/server/sonar-web/src/main/js/apps/overview/components/ApplicationLeakPeriodLegend.js b/server/sonar-web/src/main/js/apps/overview/components/ApplicationLeakPeriodLegend.tsx similarity index 78% rename from server/sonar-web/src/main/js/apps/overview/components/ApplicationLeakPeriodLegend.js rename to server/sonar-web/src/main/js/apps/overview/components/ApplicationLeakPeriodLegend.tsx index bc0704b005a..55d8c5082ce 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/ApplicationLeakPeriodLegend.js +++ b/server/sonar-web/src/main/js/apps/overview/components/ApplicationLeakPeriodLegend.tsx @@ -17,39 +17,31 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// @flow -import React from 'react'; +import * as React from 'react'; import Tooltip from '../../../components/controls/Tooltip'; import DateTooltipFormatter from '../../../components/intl/DateTooltipFormatter'; import { getApplicationLeak } from '../../../api/application'; import { translate } from '../../../helpers/l10n'; -/*:: -type Props = { - component: { key: string } -}; -*/ +interface Props { + component: string; +} -/*:: -type State = { - leaks: ?Array<{ date: string, project: string, projectName: string }> -}; -*/ +interface State { + leaks?: Array<{ date: string; project: string; projectName: string }>; +} -export default class ApplicationLeakPeriodLegend extends React.Component { - /*:: mounted: boolean; */ - /*:: props: Props; */ - state /*: State */ = { - leaks: null - }; +export default class ApplicationLeakPeriodLegend extends React.Component { + mounted = false; + state: State = {}; componentDidMount() { this.mounted = true; } - componentWillReceiveProps(nextProps /*: Props */) { - if (nextProps.component.key !== this.props.component.key) { - this.setState({ leaks: null }); + componentWillReceiveProps(nextProps: Props) { + if (nextProps.component !== this.props.component) { + this.setState({ leaks: undefined }); } } @@ -57,9 +49,9 @@ export default class ApplicationLeakPeriodLegend extends React.Component { this.mounted = false; } - fetchLeaks = (visible /*: boolean */) => { - if (visible && this.state.leaks == null) { - getApplicationLeak(this.props.component.key).then( + fetchLeaks = (visible: boolean) => { + if (visible && this.state.leaks) { + getApplicationLeak(this.props.component).then( leaks => { if (this.mounted) { this.setState({ leaks }); diff --git a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx index a9bba4a81bc..5bc3679f9df 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx +++ b/server/sonar-web/src/main/js/apps/overview/components/OverviewApp.tsx @@ -143,7 +143,9 @@ export class OverviewApp extends React.PureComponent { }; getApplicationLeakPeriod = () => - this.state.measures.find(measure => measure.metric.key === 'new_bugs') ? { index: 1 } : null; + this.state.measures.find(measure => measure.metric.key === 'new_bugs') + ? { index: 1 } + : undefined; renderLoading() { return ( diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.js b/server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.tsx similarity index 95% rename from server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.js rename to server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.tsx index cd504227511..ee95828e890 100644 --- a/server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.js +++ b/server/sonar-web/src/main/js/apps/overview/components/__tests__/ApplicationLeakPeriodLegend-test.tsx @@ -17,13 +17,12 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -// @flow -import React from 'react'; +import * as React from 'react'; import { shallow } from 'enzyme'; import ApplicationLeakPeriodLegend from '../ApplicationLeakPeriodLegend'; it('renders', () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); wrapper.setState({ leaks: [ diff --git a/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/ApplicationLeakPeriodLegend-test.js.snap b/server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/ApplicationLeakPeriodLegend-test.tsx.snap similarity index 100% rename from server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/ApplicationLeakPeriodLegend-test.js.snap rename to server/sonar-web/src/main/js/apps/overview/components/__tests__/__snapshots__/ApplicationLeakPeriodLegend-test.tsx.snap diff --git a/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.js b/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.tsx similarity index 95% rename from server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.js rename to server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.tsx index d7a1db69ffa..d6433a10e08 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.js +++ b/server/sonar-web/src/main/js/apps/overview/main/BugsAndVulnerabilities.tsx @@ -17,9 +17,9 @@ * 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 * as React from 'react'; import { Link } from 'react-router'; -import enhance from './enhance'; +import enhance, { ComposedProps } from './enhance'; import ApplicationLeakPeriodLegend from '../components/ApplicationLeakPeriodLegend'; import BubblesIcon from '../../../components/icons-components/BubblesIcon'; import BugIcon from '../../../components/icons-components/BugIcon'; @@ -29,7 +29,7 @@ import { getMetricName } from '../helpers/metrics'; import { getComponentDrilldownUrl } from '../../../helpers/urls'; import { translate } from '../../../helpers/l10n'; -class BugsAndVulnerabilities extends React.PureComponent { +export class BugsAndVulnerabilities extends React.PureComponent { renderHeader() { const { branch, component } = this.props; @@ -55,15 +55,14 @@ class BugsAndVulnerabilities extends React.PureComponent { renderLeak() { const { component, leakPeriod } = this.props; - - if (leakPeriod == null) { + if (!leakPeriod) { return null; } return (
{component.qualifier === 'APP' ? ( - + ) : ( )} @@ -130,7 +129,7 @@ class BugsAndVulnerabilities extends React.PureComponent { render() { const { measures } = this.props; const bugsMeasure = measures.find(measure => measure.metric.key === 'bugs'); - if (bugsMeasure == null) { + if (!bugsMeasure) { return null; } return ( diff --git a/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.js b/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.tsx similarity index 84% rename from server/sonar-web/src/main/js/apps/overview/main/CodeSmells.js rename to server/sonar-web/src/main/js/apps/overview/main/CodeSmells.tsx index 94786fea4f8..ac7fcd0c94c 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.js +++ b/server/sonar-web/src/main/js/apps/overview/main/CodeSmells.tsx @@ -17,46 +17,35 @@ * 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 * as React from 'react'; import { Link } from 'react-router'; -import enhance from './enhance'; -import Tooltip from '../../../components/controls/Tooltip'; +import enhance, { ComposedProps } from './enhance'; import DateFromNow from '../../../components/intl/DateFromNow'; -import DateTimeFormatter from '../../../components/intl/DateTimeFormatter'; import { getMetricName } from '../helpers/metrics'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { formatMeasure, isDiffMetric } from '../../../helpers/measures'; import { getComponentIssuesUrl } from '../../../helpers/urls'; import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon'; -class CodeSmells extends React.PureComponent { +export class CodeSmells extends React.PureComponent { renderHeader() { return this.props.renderHeader('Maintainability', translate('metric.code_smells.name')); } - renderDebt(metric, type) { + renderDebt(metric: string, type: string) { const { branch, measures, component } = this.props; const measure = measures.find(measure => measure.metric.key === metric); - const value = this.props.getValue(measure); + const value = measure ? this.props.getValue(measure) : undefined; const params = { branch, resolved: 'false', facetMode: 'effort', types: type }; if (isDiffMetric(metric)) { Object.assign(params, { sinceLeakPeriod: 'true' }); } - const tooltip = ( - - {formattedAnalysisDate => ( - {translateWithParameters('widget.as_calculated_on_x', formattedAnalysisDate)} - )} - - ); return ( - - - {formatMeasure(value, 'SHORT_WORK_DUR')} - - + + {formatMeasure(value, 'SHORT_WORK_DUR')} + ); } @@ -75,7 +64,7 @@ class CodeSmells extends React.PureComponent { ); } - renderTimeline(range, displayDate) { + renderTimeline(range: string, displayDate?: boolean) { return this.props.renderTimeline( 'sqale_index', range, @@ -85,8 +74,7 @@ class CodeSmells extends React.PureComponent { renderLeak() { const { leakPeriod } = this.props; - - if (leakPeriod == null) { + if (!leakPeriod) { return null; } @@ -152,7 +140,7 @@ class CodeSmells extends React.PureComponent { render() { const { measures } = this.props; const codeSmellsMeasure = measures.find(measure => measure.metric.key === 'code_smells'); - if (codeSmellsMeasure == null) { + if (!codeSmellsMeasure) { return null; } return ( diff --git a/server/sonar-web/src/main/js/apps/overview/main/Coverage.js b/server/sonar-web/src/main/js/apps/overview/main/Coverage.tsx similarity index 79% rename from server/sonar-web/src/main/js/apps/overview/main/Coverage.js rename to server/sonar-web/src/main/js/apps/overview/main/Coverage.tsx index 6d800e2a8f6..cd1abc807ee 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/Coverage.js +++ b/server/sonar-web/src/main/js/apps/overview/main/Coverage.tsx @@ -17,36 +17,25 @@ * 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 enhance from './enhance'; +import * as React from 'react'; +import enhance, { ComposedProps } from './enhance'; import DrilldownLink from '../../../components/shared/DrilldownLink'; import { getMetricName } from '../helpers/metrics'; import { formatMeasure, getPeriodValue } from '../../../helpers/measures'; import { translate } from '../../../helpers/l10n'; import CoverageRating from '../../../components/ui/CoverageRating'; -class Coverage extends React.PureComponent { +export class Coverage extends React.PureComponent { getCoverage() { - const { measures } = this.props; - const { value } = measures.find(measure => measure.metric.key === 'coverage'); - return Number(value); - } - - getNewCoverageMeasure() { - const { measures } = this.props; - return measures.find(measure => measure.metric.key === 'new_coverage'); - } - - getNewLinesToCover() { - const { measures } = this.props; - return measures.find(measure => measure.metric.key === 'new_lines_to_cover'); + const measure = this.props.measures.find(measure => measure.metric.key === 'coverage'); + return Number(measure ? measure.value : undefined); } renderHeader() { return this.props.renderHeader('Coverage', translate('metric.coverage.name')); } - renderTimeline(range) { + renderTimeline(range: string) { return this.props.renderTimeline('coverage', range); } @@ -62,7 +51,7 @@ class Coverage extends React.PureComponent { return (
- +
@@ -84,19 +73,16 @@ class Coverage extends React.PureComponent { } renderNewCoverage() { - const { branch, component, leakPeriod } = this.props; - const newCoverageMeasure = this.getNewCoverageMeasure(); - const newLinesToCover = this.getNewLinesToCover(); - - const newCoverageValue = newCoverageMeasure - ? getPeriodValue(newCoverageMeasure, leakPeriod.index) - : null; - const newLinesToCoverValue = newLinesToCover - ? getPeriodValue(newLinesToCover, leakPeriod.index) - : null; + const { branch, component, leakPeriod, measures } = this.props; + if (!leakPeriod) { + return null; + } + const newCoverageMeasure = measures.find(measure => measure.metric.key === 'new_coverage'); + const newCoverageValue = + newCoverageMeasure && getPeriodValue(newCoverageMeasure, leakPeriod.index); const formattedValue = - newCoverageValue != null ? ( + newCoverageMeasure && newCoverageValue !== undefined ? (
— ); + + const newLinesToCover = measures.find(measure => measure.metric.key === 'new_lines_to_cover'); + const newLinesToCoverValue = + newLinesToCover && getPeriodValue(newLinesToCover, leakPeriod.index); const label = - newLinesToCoverValue != null && newLinesToCoverValue > 0 ? ( + newLinesToCover && newLinesToCoverValue !== undefined && Number(newLinesToCoverValue) > 0 ? (
{translate('overview.coverage_on')}
@@ -129,6 +119,7 @@ class Coverage extends React.PureComponent { ) : (
{getMetricName('new_coverage')}
); + return (
{formattedValue}
@@ -152,7 +143,7 @@ class Coverage extends React.PureComponent { renderLeak() { const { leakPeriod } = this.props; - if (leakPeriod == null) { + if (!leakPeriod) { return null; } return ( @@ -167,7 +158,7 @@ class Coverage extends React.PureComponent { render() { const { measures } = this.props; const coverageMeasure = measures.find(measure => measure.metric.key === 'coverage'); - if (coverageMeasure == null) { + if (!coverageMeasure) { return null; } return ( diff --git a/server/sonar-web/src/main/js/apps/overview/main/Duplications.js b/server/sonar-web/src/main/js/apps/overview/main/Duplications.tsx similarity index 87% rename from server/sonar-web/src/main/js/apps/overview/main/Duplications.js rename to server/sonar-web/src/main/js/apps/overview/main/Duplications.tsx index 3f94296f6b3..d8a09caee40 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/Duplications.js +++ b/server/sonar-web/src/main/js/apps/overview/main/Duplications.tsx @@ -17,20 +17,20 @@ * 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 enhance from './enhance'; +import * as React from 'react'; +import enhance, { ComposedProps } from './enhance'; import DrilldownLink from '../../../components/shared/DrilldownLink'; import { getMetricName } from '../helpers/metrics'; import { formatMeasure, getPeriodValue } from '../../../helpers/measures'; import { translate } from '../../../helpers/l10n'; import DuplicationsRating from '../../../components/ui/DuplicationsRating'; -class Duplications extends React.PureComponent { +export class Duplications extends React.PureComponent { renderHeader() { return this.props.renderHeader('Duplications', translate('overview.domain.duplications')); } - renderTimeline(range) { + renderTimeline(range: string) { return this.props.renderTimeline('duplicated_lines_density', range); } @@ -40,13 +40,18 @@ class Duplications extends React.PureComponent { renderDuplications() { const { branch, component, measures } = this.props; + const measure = measures.find(measure => measure.metric.key === 'duplicated_lines_density'); + if (!measure) { + return null; + } + const duplications = Number(measure.value); return (
- +
@@ -70,20 +75,17 @@ class Duplications extends React.PureComponent { renderNewDuplications() { const { branch, component, measures, leakPeriod } = this.props; + if (!leakPeriod) { + return null; + } + const newDuplicationsMeasure = measures.find( measure => measure.metric.key === 'new_duplicated_lines_density' ); - const newLinesMeasure = measures.find(measure => measure.metric.key === 'new_lines'); - - const newDuplicationsValue = newDuplicationsMeasure - ? getPeriodValue(newDuplicationsMeasure, leakPeriod.index) - : null; - const newLinesValue = newLinesMeasure - ? getPeriodValue(newLinesMeasure, leakPeriod.index) - : null; - + const newDuplicationsValue = + newDuplicationsMeasure && getPeriodValue(newDuplicationsMeasure, leakPeriod.index); const formattedValue = - newDuplicationsValue != null ? ( + newDuplicationsMeasure && newDuplicationsValue ? (
— ); + + const newLinesMeasure = measures.find(measure => measure.metric.key === 'new_lines'); + const newLinesValue = newLinesMeasure && getPeriodValue(newLinesMeasure, leakPeriod.index); const label = - newLinesValue != null && newLinesValue > 0 ? ( + newLinesMeasure && newLinesValue !== undefined && Number(newLinesValue) > 0 ? (
{translate('overview.duplications_on')}
@@ -116,6 +121,7 @@ class Duplications extends React.PureComponent { ) : (
{getMetricName('new_duplications')}
); + return (
{formattedValue}
diff --git a/server/sonar-web/src/main/js/apps/overview/main/enhance.tsx b/server/sonar-web/src/main/js/apps/overview/main/enhance.tsx index 43e23c1715d..2b07c3c9239 100644 --- a/server/sonar-web/src/main/js/apps/overview/main/enhance.tsx +++ b/server/sonar-web/src/main/js/apps/overview/main/enhance.tsx @@ -21,7 +21,6 @@ import * as React from 'react'; import { Link } from 'react-router'; import DrilldownLink from '../../../components/shared/DrilldownLink'; import BubblesIcon from '../../../components/icons-components/BubblesIcon'; -import DateTimeFormatter from '../../../components/intl/DateTimeFormatter'; import HistoryIcon from '../../../components/icons-components/HistoryIcon'; import Rating from '../../../components/ui/Rating'; import Timeline from '../components/Timeline'; @@ -34,7 +33,7 @@ import { getRatingTooltip, MeasureEnhanced } from '../../../helpers/measures'; -import { translateWithParameters, getLocalizedMetricName } from '../../../helpers/l10n'; +import { getLocalizedMetricName } from '../../../helpers/l10n'; import { getPeriodDate } from '../../../helpers/periods'; import { getComponentDrilldownUrl, @@ -155,22 +154,10 @@ export default function enhance(ComposedComponent: React.ComponentType - {formattedAnalysisDate => ( - - {translateWithParameters('widget.as_calculated_on_x', formattedAnalysisDate)} - - )} - - ); - return ( - - - {formatMeasure(value, 'SHORT_INT')} - - + + {formatMeasure(value, 'SHORT_INT')} + ); }; @@ -209,9 +196,9 @@ export default function enhance(ComposedComponent: React.ComponentType ); diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 8144c5c5190..ac534cbda9e 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -2364,8 +2364,6 @@ overview.badges.marketing.description=This badge lets you advertise that you're overview.badges.quality_gate.alt=SonarCloud Quality Gate badge overview.badges.quality_gate.description=This badge dynamically displays the current quality gate status of your project. -widget.as_calculated_on_x=As calculated on {0} - #------------------------------------------------------------------------------ # -- 2.39.5