/* * 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 { CoverageIndicator, DuplicationsIndicator, MetricsLabel, MetricsRatingBadge, Note, PageContentFontWrapper, } from 'design-system'; import * as React from 'react'; import Measure from '../../../../components/measure/Measure'; import { duplicationRatingConverter } from '../../../../components/measure/utils'; import { translate } from '../../../../helpers/l10n'; import { formatRating } from '../../../../helpers/measures'; import { isDefined } from '../../../../helpers/types'; import { ComponentQualifier } from '../../../../types/component'; import { MetricKey, MetricType } from '../../../../types/metrics'; import { Dict } from '../../../../types/types'; import ProjectCardMeasure from './ProjectCardMeasure'; export interface ProjectCardMeasuresProps { isNewCode: boolean; measures: Dict; componentQualifier: ComponentQualifier; } function renderNewIssues(props: ProjectCardMeasuresProps) { const { measures, isNewCode } = props; if (!isNewCode) { return null; } return ( ); } function renderCoverage(props: ProjectCardMeasuresProps) { const { measures, isNewCode } = props; const coverageMetric = isNewCode ? MetricKey.new_coverage : MetricKey.coverage; return (
{measures[coverageMetric] && }
); } function renderDuplication(props: ProjectCardMeasuresProps) { const { measures, isNewCode } = props; const duplicationMetric = isNewCode ? MetricKey.new_duplicated_lines_density : MetricKey.duplicated_lines_density; const rating = measures[duplicationMetric] !== undefined ? duplicationRatingConverter(Number(measures[duplicationMetric])) : undefined; return (
{measures[duplicationMetric] != null && }
); } function renderRatings(props: ProjectCardMeasuresProps) { const { isNewCode, measures } = props; const measuresByCodeLeak = isNewCode ? [] : [ { iconLabel: translate(`metric.${MetricKey.security_issues}.short_name`), noShrink: true, metricKey: measures[MetricKey.security_issues] !== undefined ? MetricKey.security_issues : MetricKey.vulnerabilities, metricRatingKey: MetricKey.security_rating, metricType: MetricType.ShortInteger, }, { iconLabel: translate(`metric.${MetricKey.reliability_issues}.short_name`), metricKey: measures[MetricKey.reliability_issues] !== undefined ? MetricKey.reliability_issues : MetricKey.bugs, metricRatingKey: MetricKey.reliability_rating, metricType: MetricType.ShortInteger, }, { iconLabel: translate(`metric.${MetricKey.maintainability_issues}.short_name`), metricKey: measures[MetricKey.maintainability_issues] !== undefined ? MetricKey.maintainability_issues : MetricKey.code_smells, metricRatingKey: MetricKey.sqale_rating, metricType: MetricType.ShortInteger, }, ]; const measureList = [ ...measuresByCodeLeak, { iconKey: 'security_hotspots', iconLabel: translate('projects.security_hotspots_reviewed'), metricKey: isNewCode ? MetricKey.new_security_hotspots_reviewed : MetricKey.security_hotspots_reviewed, metricRatingKey: isNewCode ? MetricKey.new_security_review_rating : MetricKey.security_review_rating, metricType: MetricType.Percent, }, ]; return measureList.map((measure) => { const { iconLabel, metricKey, metricRatingKey, metricType } = measure; const value = formatRating(measures[metricRatingKey]); const measureValue = [ MetricKey.security_issues, MetricKey.reliability_issues, MetricKey.maintainability_issues, ].includes(metricKey) && measures[metricKey] ? JSON.parse(measures[metricKey] as string)?.total : measures[metricKey]; return ( ); }); } export default function ProjectCardMeasures(props: ProjectCardMeasuresProps) { const { isNewCode, measures, componentQualifier } = props; const { ncloc } = measures; if (!isNewCode && !ncloc) { return ( {componentQualifier === ComponentQualifier.Application ? translate('portfolio.app.empty') : translate('overview.project.main_branch_empty')} ); } const measureList = [ renderNewIssues(props), ...renderRatings(props), renderCoverage(props), renderDuplication(props), ].filter(isDefined); return ( {measureList.map((measure, i) => ( // eslint-disable-next-line react/no-array-index-key {measure} ))} ); }