]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-23196 Filter graph custom metrics based on current MQR mode
authorIsmail Cherri <ismail.cherri@sonarsource.com>
Mon, 28 Oct 2024 12:23:53 +0000 (13:23 +0100)
committersonartech <sonartech@sonarsource.com>
Tue, 5 Nov 2024 20:03:02 +0000 (20:03 +0000)
server/sonar-web/src/main/js/apps/projectActivity/components/__tests__/ProjectActivityApp-it.tsx
server/sonar-web/src/main/js/apps/quality-gates/components/List.tsx
server/sonar-web/src/main/js/components/activity-graph/AddGraphMetric.tsx
server/sonar-web/src/main/js/components/activity-graph/AddGraphMetricPopup.tsx
server/sonar-web/src/main/js/components/activity-graph/GraphsHeader.tsx
server/sonar-web/src/main/js/components/activity-graph/GraphsLegendItem.tsx
server/sonar-web/src/main/js/components/activity-graph/__tests__/ActivityGraph-it.tsx
server/sonar-web/src/main/js/helpers/constants.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index c44155f4a9288d5068021935dde31a725e1308d2..63deee154e38ae3805eecd322f81515040ce0477 100644 (file)
@@ -521,7 +521,11 @@ describe('graph interactions', () => {
     expect(ui.issuesPopupCell.get()).toBeInTheDocument();
   });
 
-  it('should correctly handle customizing the graph', async () => {
+  it.each([
+    ['MQR', 'true', MetricKey.maintainability_issues],
+    ['Standard', 'false', MetricKey.code_smells],
+  ])('should correctly handle customizing the graph in %s mode', async (_, mode, metric) => {
+    settingsHandler.set(SettingsKey.MQRMode, mode);
     const { ui } = getPageObject();
     renderProjectActivityAppContainer();
     await ui.appLoaded();
@@ -532,7 +536,7 @@ describe('graph interactions', () => {
 
     // Add metrics.
     await ui.openMetricsDropdown();
-    await ui.toggleMetric(MetricKey.bugs);
+    await ui.toggleMetric(metric);
     await ui.toggleMetric(MetricKey.security_hotspots_reviewed);
     await ui.closeMetricsDropdown();
 
@@ -540,7 +544,7 @@ describe('graph interactions', () => {
 
     // Remove metrics.
     await ui.openMetricsDropdown();
-    await ui.toggleMetric(MetricKey.bugs);
+    await ui.toggleMetric(metric);
     await ui.toggleMetric(MetricKey.security_hotspots_reviewed);
     await ui.closeMetricsDropdown();
 
index e5707e03241d508d4587c8838016d725f4529584..a2c29c20ff80159b7e966308955b7eb008466675 100644 (file)
@@ -103,7 +103,7 @@ export default function List({ qualityGates, currentQualityGate }: Readonly<Prop
 
                   {isAICodeAssuranceQualityGate && (
                     <Tooltip
-                      content={translate('quality_gates.ai_generated.tootltip.message')}
+                      content={translate('quality_gates.ai_generated.tooltip.message')}
                       isOpen={shouldShowQualityGateUpdateIcon ? false : undefined}
                     >
                       <span className="sw-mr-1">
index 6e9b3447c576415f0acabaa1562317523412b474..1b4ef643205864186b87f2a906339cba74966555 100644 (file)
@@ -25,7 +25,13 @@ import { Dropdown } from '~design-system';
 import { MetricKey, MetricType } from '~sonar-aligned/types/metrics';
 import {
   CCT_SOFTWARE_QUALITY_METRICS,
+  DEPRECATED_ACTIVITY_METRICS,
   HIDDEN_METRICS,
+  LEAK_CCT_SOFTWARE_QUALITY_METRICS,
+  LEAK_OLD_TAXONOMY_METRICS,
+  LEAK_OLD_TAXONOMY_RATINGS,
+  OLD_TAXONOMY_METRICS,
+  SOFTWARE_QUALITY_RATING_METRICS,
   SOFTWARE_QUALITY_RATING_METRICS_MAP,
 } from '../../helpers/constants';
 import { getLocalizedMetricName, translate } from '../../helpers/l10n';
@@ -34,6 +40,7 @@ import { Metric } from '../../types/types';
 import AddGraphMetricPopup from './AddGraphMetricPopup';
 
 interface Props {
+  isStandardMode?: boolean;
   metrics: Metric[];
   metricsTypeFilter?: string[];
   onAddMetric: (metric: string) => void;
@@ -60,10 +67,8 @@ export default class AddGraphMetric extends React.PureComponent<Props, State> {
     );
   };
 
-  filterMetricsElements = (
-    { metricsTypeFilter, metrics, selectedMetrics }: Props,
-    query: string,
-  ) => {
+  filterMetricsElements = (query: string) => {
+    const { metrics, selectedMetrics, metricsTypeFilter, isStandardMode } = this.props;
     return metrics
       .filter((metric) => {
         if (metric.hidden) {
@@ -81,6 +86,27 @@ export default class AddGraphMetric extends React.PureComponent<Props, State> {
         if (HIDDEN_METRICS.includes(metric.key as MetricKey)) {
           return false;
         }
+        if (
+          isStandardMode &&
+          [
+            ...LEAK_CCT_SOFTWARE_QUALITY_METRICS,
+            ...CCT_SOFTWARE_QUALITY_METRICS,
+            ...SOFTWARE_QUALITY_RATING_METRICS,
+          ].includes(metric.key as MetricKey)
+        ) {
+          return false;
+        }
+        if (
+          !isStandardMode &&
+          [
+            ...LEAK_OLD_TAXONOMY_METRICS,
+            ...OLD_TAXONOMY_METRICS,
+            ...LEAK_OLD_TAXONOMY_RATINGS,
+            ...DEPRECATED_ACTIVITY_METRICS,
+          ].includes(metric.key as MetricKey)
+        ) {
+          return false;
+        }
         if (Object.values(SOFTWARE_QUALITY_RATING_METRICS_MAP).includes(metric.key as MetricKey)) {
           return false;
         }
@@ -123,7 +149,7 @@ export default class AddGraphMetric extends React.PureComponent<Props, State> {
     this.setState((state) => {
       return {
         selectedMetrics: sortBy([...state.selectedMetrics, metric]),
-        metrics: this.filterMetricsElements(this.props, state.query),
+        metrics: this.filterMetricsElements(state.query),
       };
     });
   };
@@ -140,7 +166,7 @@ export default class AddGraphMetric extends React.PureComponent<Props, State> {
 
   render() {
     const { query } = this.state;
-    const filteredMetrics = this.filterMetricsElements(this.props, query);
+    const filteredMetrics = this.filterMetricsElements(query);
     const selectedMetrics = this.getSelectedMetricsElements(
       this.props.metrics,
       this.props.selectedMetrics,
index 54f5c21705cc5c224bfa3cce4dcd389220bfa924..07d000626546ff1d9fc32d16b188719338837447 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 
-import * as React from 'react';
-import { FormattedMessage, useIntl } from 'react-intl';
-import { Badge, FlagMessage, MultiSelectMenu } from '~design-system';
+import { ReactNode, useCallback } from 'react';
+import { FlagMessage, MultiSelectMenu } from '~design-system';
 import { MetricKey } from '~sonar-aligned/types/metrics';
-import { DEPRECATED_ACTIVITY_METRICS } from '../../helpers/constants';
 import { getLocalizedMetricName, translate, translateWithParameters } from '../../helpers/l10n';
-import { getDeprecatedTranslationKeyForTooltip } from './utils';
 
 export interface AddGraphMetricPopupProps {
   elements: string[];
@@ -42,8 +39,7 @@ export default function AddGraphMetricPopup({
   metricsTypeFilter,
   ...props
 }: Readonly<AddGraphMetricPopupProps>) {
-  const intl = useIntl();
-  let footerNode: React.ReactNode = '';
+  let footerNode: ReactNode = '';
 
   if (props.selectedElements.length >= 6) {
     footerNode = (
@@ -65,37 +61,9 @@ export default function AddGraphMetricPopup({
     );
   }
 
-  const renderAriaLabel = (key: MetricKey) => {
-    const metricName = getLocalizedMetricName({ key });
-    const isDeprecated = DEPRECATED_ACTIVITY_METRICS.includes(key);
-
-    return isDeprecated
-      ? `${metricName} (${intl.formatMessage({ id: 'deprecated' })})`
-      : metricName;
-  };
-
-  const renderLabel = (key: MetricKey) => {
-    const metricName = getLocalizedMetricName({ key });
-    const isDeprecated = DEPRECATED_ACTIVITY_METRICS.includes(key);
-
-    return (
-      <>
-        {metricName}
-        {isDeprecated && (
-          <Badge className="sw-ml-1">{intl.formatMessage({ id: 'deprecated' })}</Badge>
-        )}
-      </>
-    );
-  };
-
-  const renderTooltip = (key: MetricKey) => {
-    const isDeprecated = DEPRECATED_ACTIVITY_METRICS.includes(key);
-    if (isDeprecated) {
-      return <FormattedMessage id={getDeprecatedTranslationKeyForTooltip(key)} tagName="div" />;
-    }
-
-    return null;
-  };
+  const renderLabel = useCallback((key: MetricKey) => {
+    return getLocalizedMetricName({ key });
+  }, []);
 
   return (
     <MultiSelectMenu
@@ -111,9 +79,8 @@ export default function AddGraphMetricPopup({
       onSelect={(item: string) => elements.includes(item) && props.onSelect(item)}
       onUnselect={props.onUnselect}
       placeholder={translate('search.search_for_metrics')}
-      renderAriaLabel={renderAriaLabel}
+      renderAriaLabel={renderLabel}
       renderLabel={renderLabel}
-      renderTooltip={renderTooltip}
       selectedElements={props.selectedElements}
       listSize={0}
     />
index 35d1150b9cddbf4af354bf626d51b730b67261e4..88785de65ceff2c495f11f0e701c51e8b6b70da4 100644 (file)
@@ -21,6 +21,7 @@
 import { ButtonGroup, InputSize, Select } from '@sonarsource/echoes-react';
 import * as React from 'react';
 import { translate } from '../../helpers/l10n';
+import { useStandardExperienceMode } from '../../queries/settings';
 import { GraphType } from '../../types/project-activity';
 import { Metric } from '../../types/types';
 import AddGraphMetric from './AddGraphMetric';
@@ -47,6 +48,8 @@ export default function GraphsHeader(props: Readonly<Props>) {
     selectedMetrics = [],
   } = props;
 
+  const { data: isStandardMode } = useStandardExperienceMode();
+
   const handleGraphChange = React.useCallback(
     (value: GraphType) => {
       if (value !== graph) {
@@ -87,6 +90,7 @@ export default function GraphsHeader(props: Readonly<Props>) {
               metricsTypeFilter={metricsTypeFilter}
               onRemoveMetric={props.onRemoveCustomMetric}
               selectedMetrics={selectedMetrics}
+              isStandardMode={isStandardMode}
             />
           )}
       </ButtonGroup>
index 90e841ffd217491b9941adab698829d6c68eea38..dbd3729e9141154131a47ec83e5dd58276b4ca8a 100644 (file)
  */
 
 import styled from '@emotion/styled';
+import { ButtonIcon, ButtonSize, IconWarning, IconX } from '@sonarsource/echoes-react';
 import classNames from 'classnames';
-import { FormattedMessage, useIntl } from 'react-intl';
-import { Badge, CloseIcon, FlagWarningIcon, InteractiveIcon, themeBorder } from '~design-system';
-import { MetricKey } from '~sonar-aligned/types/metrics';
-import { DEPRECATED_ACTIVITY_METRICS } from '../../helpers/constants';
+import { themeBorder } from '~design-system';
 import { translateWithParameters } from '../../helpers/l10n';
-import Tooltip from '../controls/Tooltip';
 import { ChartLegend } from './ChartLegend';
-import { getDeprecatedTranslationKeyForTooltip } from './utils';
 
 interface Props {
   className?: string;
@@ -45,11 +41,8 @@ export function GraphsLegendItem({
   name,
   removeMetric,
   showWarning,
-}: Props) {
-  const intl = useIntl();
-
+}: Readonly<Props>) {
   const isActionable = removeMetric !== undefined;
-  const isDeprecated = DEPRECATED_ACTIVITY_METRICS.includes(metric as MetricKey);
 
   return (
     <StyledLegendItem
@@ -57,33 +50,19 @@ export function GraphsLegendItem({
       isActionable={isActionable}
     >
       {showWarning ? (
-        <FlagWarningIcon className="sw-mr-2" />
+        <IconWarning className="sw-mr-2" />
       ) : (
         <ChartLegend className="sw-mr-2" index={index} />
       )}
       <span className="sw-typo-default" style={{ color: 'var(--echoes-color-text-subdued)' }}>
         {name}
       </span>
-      {isDeprecated && (
-        <Tooltip
-          content={
-            <FormattedMessage
-              id={getDeprecatedTranslationKeyForTooltip(metric as MetricKey)}
-              tagName="div"
-            />
-          }
-        >
-          <div>
-            <Badge className="sw-ml-1">{intl.formatMessage({ id: 'deprecated' })}</Badge>
-          </div>
-        </Tooltip>
-      )}
       {isActionable && (
-        <InteractiveIcon
-          Icon={CloseIcon}
-          aria-label={translateWithParameters('project_activity.graphs.custom.remove_metric', name)}
-          className="sw-ml-2"
-          size="small"
+        <ButtonIcon
+          size={ButtonSize.Medium}
+          Icon={IconX}
+          ariaLabel={translateWithParameters('project_activity.graphs.custom.remove_metric', name)}
+          className="sw-ml-2 sw-border-0"
           onClick={() => removeMetric(metric)}
         />
       )}
index 634b4ac1845b1de016e24acdaa5b9518fb6c7271..e144fcf292971afb0386090ab88b162dd0e1adda 100644 (file)
@@ -29,16 +29,15 @@ import {
   byText,
 } from '~sonar-aligned/helpers/testSelector';
 import { MetricKey, MetricType } from '~sonar-aligned/types/metrics';
-import {
-  CCT_SOFTWARE_QUALITY_METRICS,
-  DEPRECATED_ACTIVITY_METRICS,
-} from '../../../helpers/constants';
+import { settingsHandler } from '../../../apps/issues/test-utils';
+import { CCT_SOFTWARE_QUALITY_METRICS } from '../../../helpers/constants';
 import { parseDate } from '../../../helpers/dates';
 import { mockHistoryItem, mockMeasureHistory } from '../../../helpers/mocks/project-activity';
 import { mockMetric } from '../../../helpers/testMocks';
 import { renderComponent } from '../../../helpers/testReactTestingUtils';
 import { ComponentPropsType } from '../../../helpers/testUtils';
 import { GraphType, MeasureHistory } from '../../../types/project-activity';
+import { SettingsKey } from '../../../types/settings';
 import { Metric } from '../../../types/types';
 import GraphsHeader from '../GraphsHeader';
 import GraphsHistory from '../GraphsHistory';
@@ -55,7 +54,11 @@ describe('rendering', () => {
     expect(await screen.findByText('loading')).toBeInTheDocument();
   });
 
-  it('should show the correct legend items', async () => {
+  it.each([
+    ['MQR', 'true', MetricKey.maintainability_issues],
+    ['Standard', 'false', MetricKey.code_smells],
+  ])('should show the correct legend items in %s mode', async (_, mode, metric) => {
+    settingsHandler.set(SettingsKey.MQRMode, mode);
     const { ui, user } = getPageObject();
     renderActivityGraph();
 
@@ -66,12 +69,12 @@ describe('rendering', () => {
     // Switch to custom graph.
     await ui.changeGraphType(GraphType.custom);
     await ui.openAddMetrics();
-    await ui.clickOnMetric(MetricKey.bugs);
+    await ui.clickOnMetric(metric);
     await ui.clickOnMetric(MetricKey.test_failures);
     await user.keyboard('{Escape}');
 
     // These legend items are interactive (interaction tested below).
-    expect(ui.legendRemoveMetricBtn(MetricKey.bugs).get()).toBeInTheDocument();
+    expect(ui.legendRemoveMetricBtn(metric).get()).toBeInTheDocument();
     expect(ui.legendRemoveMetricBtn(MetricKey.test_failures).get()).toBeInTheDocument();
 
     // Shows warning for metrics with no data.
@@ -118,70 +121,80 @@ describe('data table modal', () => {
   });
 });
 
-it('should correctly handle adding/removing custom metrics', async () => {
-  const { ui } = getPageObject();
-  renderActivityGraph();
-
-  // Change graph type to "Custom".
-  await ui.changeGraphType(GraphType.custom);
+it.each([
+  [
+    'MQR',
+    'true',
+    MetricKey.reliability_issues,
+    MetricKey.maintainability_issues,
+    MetricKey.security_issues,
+  ],
+  ['Standard', 'false', MetricKey.bugs, MetricKey.code_smells, MetricKey.vulnerabilities],
+])(
+  'should correctly handle adding/removing custom metrics in $s mode',
+  async (_, mode, bugs, codeSmells, vulnerabilities) => {
+    settingsHandler.set(SettingsKey.MQRMode, mode);
+    const { ui } = getPageObject();
+    renderActivityGraph();
 
-  // Open the "Add metrics" dropdown button; select some metrics.
-  await ui.openAddMetrics();
+    // Change graph type to "Custom".
+    await ui.changeGraphType(GraphType.custom);
 
-  // We should not see DATA type or New Code metrics.
-  expect(ui.newBugsCheckbox.query()).not.toBeInTheDocument();
-  expect(ui.burnedBudgetCheckbox.query()).not.toBeInTheDocument();
+    // Open the "Add metrics" dropdown button; select some metrics.
+    await ui.openAddMetrics();
 
-  // Select 3 Int types.
-  await ui.clickOnMetric(MetricKey.bugs);
-  await ui.clickOnMetric(MetricKey.code_smells);
-  await ui.clickOnMetric(MetricKey.confirmed_issues);
-  // Select 1 Percent type.
-  await ui.clickOnMetric(MetricKey.coverage);
+    // We should not see DATA type or New Code metrics.
+    expect(ui.metricCheckbox(`new_${bugs}`).query()).not.toBeInTheDocument();
+    expect(ui.burnedBudgetCheckbox.query()).not.toBeInTheDocument();
 
-  // We should see 2 graphs, correctly labelled.
-  expect(ui.graphs.getAll()).toHaveLength(2);
+    // Select 3 Int types.
+    await ui.clickOnMetric(bugs);
+    await ui.clickOnMetric(codeSmells);
+    await ui.clickOnMetric(MetricKey.accepted_issues);
+    // Select 1 Percent type.
+    await ui.clickOnMetric(MetricKey.coverage);
 
-  // old types and confirmed metrics should be deprecated and show a badge (both in dropdown and in legend)
-  expect(ui.deprecatedBadge.getAll()).toHaveLength(6);
+    // We should see 2 graphs, correctly labelled.
+    expect(ui.graphs.getAll()).toHaveLength(2);
 
-  // We cannot select anymore Int types. It should hide options, and show an alert.
-  expect(ui.vulnerabilityCheckbox.query()).not.toBeInTheDocument();
-  expect(ui.hiddenOptionsAlert.get()).toBeInTheDocument();
+    // We cannot select anymore Int types. It should hide options, and show an alert.
+    expect(ui.metricCheckbox(vulnerabilities).query()).not.toBeInTheDocument();
+    expect(ui.hiddenOptionsAlert.get()).toBeInTheDocument();
 
-  // Select 2 more Percent types.
-  await ui.clickOnMetric(MetricKey.duplicated_lines_density);
-  await ui.clickOnMetric(MetricKey.test_success_density);
+    // Select 2 more Percent types.
+    await ui.clickOnMetric(MetricKey.duplicated_lines_density);
+    await ui.clickOnMetric(MetricKey.test_success_density);
 
-  // We cannot select anymore options. It should disable all remaining options, and
-  // show a different alert.
-  expect(ui.maxOptionsAlert.get()).toBeInTheDocument();
-  expect(ui.vulnerabilityCheckbox.get()).toBeDisabled();
+    // We cannot select anymore options. It should disable all remaining options, and
+    // show a different alert.
+    expect(ui.maxOptionsAlert.get()).toBeInTheDocument();
+    expect(ui.metricCheckbox(vulnerabilities).get()).toBeDisabled();
 
-  // Disable a few options.
-  await ui.clickOnMetric(MetricKey.bugs);
-  await ui.clickOnMetric(MetricKey.code_smells);
-  await ui.clickOnMetric(MetricKey.coverage);
+    // Disable a few options.
+    await ui.clickOnMetric(bugs);
+    await ui.clickOnMetric(codeSmells);
+    await ui.clickOnMetric(MetricKey.coverage);
 
-  // Search for option and select it
-  await ui.searchForMetric('maintainability');
-  expect(ui.vulnerabilityCheckbox.query()).not.toBeInTheDocument();
-  await ui.clickOnMetric(MetricKey.maintainability_issues);
+    // Search for option and select it
+    await ui.searchForMetric('condition');
+    expect(ui.metricCheckbox(MetricKey.branch_coverage).query()).not.toBeInTheDocument();
+    await ui.clickOnMetric(MetricKey.conditions_to_cover);
 
-  // Disable percentage metrics by clicking on the legend items.
-  await ui.removeMetric(MetricKey.duplicated_lines_density);
-  await ui.removeMetric(MetricKey.test_success_density);
+    // Disable percentage metrics by clicking on the legend items.
+    await ui.removeMetric(MetricKey.duplicated_lines_density);
+    await ui.removeMetric(MetricKey.test_success_density);
 
-  // We should see 1 graph
-  expect(ui.graphs.getAll()).toHaveLength(1);
+    // We should see 1 graph
+    expect(ui.graphs.getAll()).toHaveLength(1);
 
-  // Disable final number metrics
-  await ui.removeMetric(MetricKey.confirmed_issues);
-  await ui.removeMetric(MetricKey.maintainability_issues);
+    // Disable final number metrics
+    await ui.removeMetric(MetricKey.accepted_issues);
+    await ui.removeMetric(MetricKey.conditions_to_cover);
 
-  // Should show message that there's no data to be rendered.
-  expect(ui.noDataText.get()).toBeInTheDocument();
-});
+    // Should show message that there's no data to be rendered.
+    expect(ui.noDataText.get()).toBeInTheDocument();
+  },
+);
 
 function getPageObject() {
   const user = userEvent.setup();
@@ -191,18 +204,15 @@ function getPageObject() {
 
     // Add/remove metrics.
     addMetricBtn: byRole('button', { name: 'project_activity.graphs.custom.add' }),
-    deprecatedBadge: byText('deprecated'),
     maintainabilityIssuesCheckbox: byRole('checkbox', { name: MetricKey.maintainability_issues }),
     newBugsCheckbox: byRole('checkbox', { name: MetricKey.new_bugs }),
     burnedBudgetCheckbox: byRole('checkbox', { name: MetricKey.burned_budget }),
-    vulnerabilityCheckbox: byRole('checkbox', {
-      name: `${MetricKey.vulnerabilities} (deprecated)`,
-    }),
     hiddenOptionsAlert: byText('project_activity.graphs.custom.type_x_message', {
       exact: false,
     }),
     maxOptionsAlert: byText('project_activity.graphs.custom.add_metric_info'),
     filterMetrics: byPlaceholderText('search.search_for_metrics'),
+    metricCheckbox: (name: string) => byRole('checkbox', { name }),
     legendRemoveMetricBtn: (key: string) =>
       byRole('button', { name: `project_activity.graphs.custom.remove_metric.${key}` }),
     getLegendItem: (name: string) => {
@@ -243,11 +253,7 @@ function getPageObject() {
         await user.type(ui.filterMetrics.get(), text);
       },
       async clickOnMetric(name: MetricKey) {
-        await user.click(
-          screen.getByRole('checkbox', {
-            name: DEPRECATED_ACTIVITY_METRICS.includes(name) ? `${name} (deprecated)` : name,
-          }),
-        );
+        await user.click(ui.metricCheckbox(name).get());
       },
       async removeMetric(metric: MetricKey) {
         await user.click(ui.legendRemoveMetricBtn(metric).get());
@@ -273,18 +279,22 @@ function renderActivityGraph(
     const measuresHistory: MeasureHistory[] = [];
     const metrics: Metric[] = [];
     [
+      MetricKey.accepted_issues,
       MetricKey.violations,
       MetricKey.bugs,
       MetricKey.code_smells,
-      MetricKey.confirmed_issues,
-      MetricKey.maintainability_issues,
       MetricKey.vulnerabilities,
+      MetricKey.maintainability_issues,
+      MetricKey.reliability_issues,
+      MetricKey.security_issues,
       MetricKey.blocker_violations,
       MetricKey.lines_to_cover,
       MetricKey.uncovered_lines,
       MetricKey.coverage,
       MetricKey.duplicated_lines_density,
       MetricKey.test_success_density,
+      MetricKey.branch_coverage,
+      MetricKey.conditions_to_cover,
     ].forEach((metric) => {
       const history = times(HISTORY_COUNT - 2, (i) => {
         const date = parseDate(START_DATE);
index 2145390f9090879615d689d1f23bbc935e47d81c..cf169fbcf944f4b51e1088cfe889e28b9daf9a37 100644 (file)
@@ -200,7 +200,6 @@ export const HIDDEN_METRICS = [
 ];
 
 export const DEPRECATED_ACTIVITY_METRICS = [
-  ...OLD_TAXONOMY_METRICS,
   MetricKey.blocker_violations,
   MetricKey.critical_violations,
   MetricKey.major_violations,
@@ -268,6 +267,11 @@ export const SOFTWARE_QUALITY_RATING_METRICS = [
   MetricKey.new_software_quality_reliability_remediation_effort,
   MetricKey.new_software_quality_security_remediation_effort,
   MetricKey.new_software_quality_maintainability_debt_ratio,
+  MetricKey.software_quality_blocker_issues,
+  MetricKey.software_quality_high_issues,
+  MetricKey.software_quality_medium_issues,
+  MetricKey.software_quality_low_issues,
+  MetricKey.software_quality_info_issues,
 ];
 
 export const PROJECT_KEY_MAX_LEN = 400;
index ab785a5a0ebb84f9dd5131ffc3eb5e1319eb1be0..a352da7def547945b90d49f4ae4021d758429fea 100644 (file)
@@ -2306,7 +2306,6 @@ quality_profiles.cannot_associate_projects_no_rules=You must activate at least 1
 quality_profiles.cannot_set_default_no_rules=You must activate at least 1 rule before you can make this profile the default profile.
 quality_profiles.warning.used_by_projects_no_rules=The current profile is used on several projects, but it has no active rules. Please activate at least 1 rule for this profile.
 quality_profiles.warning.is_default_no_rules=The current profile is the default profile, but it has no active rules. Please activate at least 1 rule for this profile.
-quality_profiles.x_sonarway_missing_rules={linkCount} Sonar way {count, plural, one {rule} other {rules}} not included
 quality_profiles.parent=Parent
 quality_profiles.parameter_set_to=Parameter {0} set to {1}
 quality_profile.summary_additional={count} additional {count, plural, one {rule} other {rules}}
@@ -2555,7 +2554,7 @@ quality_gates.cayc.banner.description2=It ensures that:
 quality_gates.cayc_unfollow.description=You may click unlock to edit this quality gate. Adding extra conditions to a compliant quality gate can result in drawbacks. Are you reconsidering {cayc_link}? We strongly recommend this methodology to achieve a Clean Code status.
 quality_gates.cayc.review_update_modal.add_condition.header= {0} condition(s) on new code will be added
 quality_gates.cayc.review_update_modal.modify_condition.header= {0} condition(s) on new code will be modified
-quality_gates.ai_generated.tootltip.message=Sonar way ensures clean AI-generated code
+quality_gates.ai_generated.tooltip.message=Sonar way ensures clean AI-generated code
 quality_gates.ai_generated.description=Sonar way ensures {link}
 quality_gates.ai_generated.description.clean_ai_generated_code=clean AI-generated code
 quality_gates.mqr_mode_update.tooltip.message=Update the metrics of this quality gate
@@ -2911,7 +2910,6 @@ email_notification.form.save_configuration=Save configuration
 email_notification.form.save_configuration.create_success=Email configuration saved successfully.
 email_notification.form.save_configuration.update_success=Email configuration updated successfully.
 email_notification.form.delete_configuration=Delete configuration
-email_notification.state.value_should_be_valid_email=A valid email address is required.
 email_notification.overview.heading=SMTP configuration settings
 email_notification.overview.authentication_type=Authentication type
 email_notification.overview.private=Hidden for security reasons
@@ -3722,6 +3720,38 @@ metric.new_reliability_issues.short_name=New Reliability
 metric.new_security_issues.name=New Security Issues
 metric.new_security_issues.description=New security issues
 metric.new_security_issues.short_name=New Security
+metric.software_quality_blocker_issues.description=Blocker issues
+metric.software_quality_blocker_issues.name=Blocker Issues
+metric.software_quality_high_issues.description=Critical issues
+metric.software_quality_high_issues.name=Critical Issues
+metric.software_quality_info_issues.description=Info issues
+metric.software_quality_info_issues.name=Info Issues
+metric.software_quality_medium_issues.description=Major issues
+metric.software_quality_medium_issues.name=Major Issues
+metric.software_quality_low_issues.description=Minor issues
+metric.software_quality_low_issues.name=Minor Issues
+metric.new_software_quality_blocker_issues.description=New Blocker issues
+metric.new_software_quality_blocker_issues.name=New Blocker Issues
+metric.new_software_quality_high_issues.description=New Critical issues
+metric.new_software_quality_high_issues.name=New Critical Issues
+metric.new_software_quality_info_issues.description=New Info issues
+metric.new_software_quality_info_issues.name=New Info Issues
+metric.new_software_quality_medium_issues.description=New Major issues
+metric.new_software_quality_medium_issues.name=New Major Issues
+metric.new_software_quality_low_issues.description=New Minor issues
+metric.new_software_quality_low_issues.name=New Minor Issues
+metric.software_quality_maintainability_issues.name=Maintainability Issues
+metric.software_quality_maintainability_issues.description=Maintainability issues
+metric.software_quality_reliability_issues.name=Reliability Issues
+metric.software_quality_reliability_issues.description=Reliability issues
+metric.software_quality_security_issues.name=Security Issues
+metric.software_quality_security_issues.description=Security issues
+metric.new_software_quality_maintainability_issues.name=New Maintainability Issues
+metric.new_software_quality_maintainability_issues.description=New maintainability issues
+metric.new_software_quality_reliability_issues.name=New Reliability Issues
+metric.new_software_quality_reliability_issues.description=New reliability issues
+metric.new_software_quality_security_issues.name=New Security Issues
+metric.new_software_quality_security_issues.description=New security issues
 
 #------------------------------------------------------------------------------
 #
@@ -4294,7 +4324,6 @@ overview.pull_request.fixed_issues=Fixed issues
 overview.pull_request.fixed_issues.help=Estimation of issues fixed by this PR
 overview.pull_request.fixed_issues.disclaimer=Only issues fixed on the files modified by the pull request are taken into account. Issues incidentally fixed on unmodified files are not counted.
 overview.pull_request.fixed_issues.disclaimer.2=When the pull request and the target branch are not synchronized, issues introduced on the target branch may be incorrectly considered fixed by the pull request. Rebasing the pull request would give an updated value.
-overview.accepted_issues=Accepted issues
 overview.accepted_issues.help=Valid issues that were not fixed
 overview.quality_gate=Quality Gate
 overview.quality_gate_x=Quality Gate: {0}
@@ -4872,7 +4901,6 @@ onboarding.create_project.gitlab.subtitle=Import projects from one of your GitLa
 onboarding.create_project.gitlab.subtitle.with_monorepo=Import projects from one of your GitLab groups or {monorepoSetupLink}.
 onboarding.create_project.gitlab.no_projects=No projects could be fetched from GitLab. Contact your system administrator, or {link}.
 onboarding.create_project.gitlab.link=See on GitLab
-onboarding.create_project.monorepo.no_projects=No projects could be fetch from {almKey}. Contact your system administrator.
 onboarding.create_project.bitbucket.title=Bitbucket Server project onboarding
 onboarding.create_project.bitbucket.subtitle=Import projects from one of your Bitbucket server workspaces
 onboarding.create_project.bitbucket.subtitle.with_monorepo=Import projects from one of your Bitbucket server workspaces or {monorepoSetupLink}.
@@ -4904,7 +4932,6 @@ onboarding.create_project.monorepo.warning.message_admin.link=DevOps Platform in
 
 onboarding.create_project.new_code_definition.title=Set up project for Clean as You Code
 onboarding.create_x_project.new_code_definition.title=Set up {count, plural, one {project} other {# projects}} for Clean as You Code
-onboarding.create_project.new_code_definition.title=Set up project for Clean as You Code
 onboarding.create_project.new_code_definition.description=The new code definition sets which part of your code will be considered new code. This helps you focus attention on the most recent changes to your project, enabling you to follow the Clean as You Code methodology. Learn more: {link}
 onboarding.create_project.new_code_definition.description.link=Defining New Code
 onboarding.create_project.new_code_definition.create_x_projects=Create {count, plural, one {project} other {# projects}}