--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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 { Note } from 'design-system';
+import React from 'react';
+import { FormattedMessage } from 'react-intl';
+import { formatMeasure } from '~sonar-aligned/helpers/measures';
+import { MetricKey, MetricType } from '~sonar-aligned/types/metrics';
+import { findMeasure } from '../../../helpers/measures';
+import { MeasureEnhanced } from '../../../types/types';
+
+interface Props {
+ measures: MeasureEnhanced[];
+ overallMetric: MetricKey;
+}
+
+export default function AfterMergeNote({ measures, overallMetric }: Readonly<Props>) {
+ const afterMergeValue = findMeasure(measures, overallMetric)?.value;
+
+ return afterMergeValue ? (
+ <Note className="sw-mt-2 sw-body-xs sw-inline-block">
+ <strong className="sw-mr-1">{formatMeasure(afterMergeValue, MetricType.Percent)}</strong>
+ <FormattedMessage id="component_measures.facet_category.overall_category.estimated" />
+ </Note>
+ ) : null;
+}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { LinkHighlight, LinkStandalone } from '@sonarsource/echoes-react';
import classNames from 'classnames';
-import {
- ContentLink,
- CoverageIndicator,
- DuplicationsIndicator,
- LightLabel,
- TextError,
-} from 'design-system';
+import { CoverageIndicator, DuplicationsIndicator, LightLabel, TextError } from 'design-system';
import * as React from 'react';
import { FormattedMessage, useIntl } from 'react-intl';
import { To } from 'react-router-dom';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { findMeasure, localizeMetric } from '../../../helpers/measures';
import { getComponentDrilldownUrl } from '../../../helpers/urls';
+import { isPullRequest } from '../../../sonar-aligned/helpers/branch-like';
import { BranchLike } from '../../../types/branch-like';
import { QualityGateStatusConditionEnhanced } from '../../../types/quality-gates';
import { MeasureEnhanced } from '../../../types/types';
getConditionRequiredLabel,
getMeasurementMetricKey,
} from '../utils';
+import AfterMergeNote from './AfterMergeNote';
import MeasuresCard from './MeasuresCard';
interface Props {
conditions: QualityGateStatusConditionEnhanced[];
conditionMetric: MetricKey;
linesMetric: MetricKey;
+ overallConditionMetric?: MetricKey;
useDiffMetric?: boolean;
showRequired?: boolean;
}
measures,
conditions,
conditionMetric,
+ overallConditionMetric,
linesMetric,
useDiffMetric = false,
showRequired = false,
id={linesLabel}
values={{
link: (
- <ContentLink
+ <LinkStandalone
+ highlight={LinkHighlight.Default}
aria-label={translateWithParameters(
'overview.see_more_details_on_x_y',
linesValue ?? '0',
to={linesUrl}
>
{formatMeasure(linesValue ?? '0', MetricType.ShortInteger)}
- </ContentLink>
+ </LinkStandalone>
),
}}
/>
</LightLabel>
</div>
+ {overallConditionMetric && isPullRequest(branchLike) && (
+ <AfterMergeNote measures={measures} overallMetric={overallConditionMetric} />
+ )}
</MeasuresCard>
);
}
})}
conditions={conditions}
conditionMetric={MetricKey.new_coverage}
+ overallConditionMetric={MetricKey.coverage}
linesMetric={MetricKey.new_lines_to_cover}
measures={measures}
showRequired
})}
conditions={conditions}
conditionMetric={MetricKey.new_duplicated_lines_density}
+ overallConditionMetric={MetricKey.duplicated_lines_density}
linesMetric={MetricKey.new_lines}
measures={measures}
useDiffMetric
mockMeasure({
metric: MetricKey.new_coverage,
}),
+ mockMeasure({
+ metric: MetricKey.coverage,
+ }),
mockMeasure({
metric: MetricKey.duplicated_lines,
}),
},
metrics: [
mockMetric({ key: MetricKey.new_coverage }),
+ mockMetric({ key: MetricKey.coverage }),
mockMetric({ key: MetricKey.duplicated_lines }),
mockMetric({ key: MetricKey.new_lines, type: MetricType.ShortInteger }),
mockMetric({ key: MetricKey.new_bugs, type: MetricType.Integer }),
expect(screen.getByLabelText('overview.quality_gate_x.overview.gate.OK')).toBeInTheDocument();
expect(screen.getByText('metric.new_lines.name')).toBeInTheDocument();
+ expect(
+ screen.getByText('component_measures.facet_category.overall_category.estimated'),
+ ).toBeInTheDocument();
expect(screen.getByText(/overview.last_analysis_x/)).toBeInTheDocument();
});
overview.new_coverage.on_x_new_lines=On {link} New Lines to cover.
overview.coverage.on_x_new_lines=On {link} lines to cover.
overview.new_duplicated_lines_density.on_x_new_lines=On {link} New Lines.
-overview.duplicated_lines_density.on_x_new_lines=On {link} lines.
-overview.quality_gate.x_estimated_after_merge={value} Estimated after merge
+overview.duplicated_lines_density.on_x_new_lines=On {link} lines.
overview.quality_gate.require_fixing={count, plural, one {requires} other {require}} fixing
overview.quality_gate.require_reviewing={count, plural, one {requires} other {require}} reviewing
overview.quality_gate.required_x=Required {operator} {requirement}