You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MeasureHeader.tsx 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2024 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import { LinkStandalone } from '@sonarsource/echoes-react';
  21. import classNames from 'classnames';
  22. import { MetricsLabel, MetricsRatingBadge } from 'design-system';
  23. import * as React from 'react';
  24. import LanguageDistribution from '../../../components/charts/LanguageDistribution';
  25. import Tooltip from '../../../components/controls/Tooltip';
  26. import Measure from '../../../components/measure/Measure';
  27. import { getLocalizedMetricName, translate, translateWithParameters } from '../../../helpers/l10n';
  28. import { formatMeasure, isDiffMetric } from '../../../helpers/measures';
  29. import { getMeasureHistoryUrl } from '../../../helpers/urls';
  30. import { BranchLike } from '../../../types/branch-like';
  31. import { ComponentQualifier } from '../../../types/component';
  32. import { MetricKey, MetricType } from '../../../types/metrics';
  33. import { ComponentMeasure, Metric, Period, Measure as TypeMeasure } from '../../../types/types';
  34. import { getMetricSubnavigationName, hasFullMeasures } from '../utils';
  35. import LeakPeriodLegend from './LeakPeriodLegend';
  36. interface Props {
  37. branchLike?: BranchLike;
  38. component: ComponentMeasure;
  39. leakPeriod?: Period;
  40. measureValue?: string;
  41. metric: Metric;
  42. secondaryMeasure?: TypeMeasure;
  43. }
  44. export default function MeasureHeader(props: Readonly<Props>) {
  45. const { branchLike, component, leakPeriod, measureValue, metric, secondaryMeasure } = props;
  46. const isDiff = isDiffMetric(metric.key);
  47. const hasHistory =
  48. [
  49. ComponentQualifier.Portfolio,
  50. ComponentQualifier.SubPortfolio,
  51. ComponentQualifier.Application,
  52. ComponentQualifier.Project,
  53. ].includes(component.qualifier as ComponentQualifier) && hasFullMeasures(branchLike);
  54. const displayLeak = hasFullMeasures(branchLike);
  55. const title = getMetricSubnavigationName(metric, getLocalizedMetricName, isDiff);
  56. return (
  57. <div className="sw-mb-4">
  58. <div className="sw-flex sw-items-center sw-justify-between sw-gap-4">
  59. <div className="it__measure-details-metric sw-flex sw-items-center sw-gap-1">
  60. <strong className="sw-body-md-highlight">{title}</strong>
  61. <div className="sw-flex sw-items-center sw-ml-2">
  62. <Measure
  63. className={classNames('it__measure-details-value sw-body-md')}
  64. metricKey={metric.key}
  65. metricType={metric.type}
  66. value={measureValue}
  67. ratingComponent={
  68. <MetricsRatingBadge
  69. label={
  70. measureValue
  71. ? translateWithParameters(
  72. 'metric.has_rating_X',
  73. formatMeasure(measureValue, MetricType.Rating),
  74. )
  75. : translate('metric.no_rating')
  76. }
  77. rating={formatMeasure(measureValue, MetricType.Rating) as MetricsLabel}
  78. />
  79. }
  80. />
  81. </div>
  82. {!isDiff && hasHistory && (
  83. <Tooltip overlay={translate('component_measures.show_metric_history')}>
  84. <span className="sw-ml-4">
  85. <LinkStandalone
  86. className="it__show-history-link sw-font-semibold"
  87. to={getMeasureHistoryUrl(component.key, metric.key, branchLike)}
  88. >
  89. {translate('component_measures.see_metric_history')}
  90. </LinkStandalone>
  91. </span>
  92. </Tooltip>
  93. )}
  94. </div>
  95. {displayLeak && leakPeriod && (
  96. <LeakPeriodLegend component={component} period={leakPeriod} />
  97. )}
  98. </div>
  99. {secondaryMeasure &&
  100. secondaryMeasure.metric === MetricKey.ncloc_language_distribution &&
  101. secondaryMeasure.value !== undefined && (
  102. <div className="sw-inline-block sw-mt-2">
  103. <LanguageDistribution distribution={secondaryMeasure.value} />
  104. </div>
  105. )}
  106. </div>
  107. );
  108. }