/* * 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 { Spinner } from '@sonarsource/echoes-react'; import { Card, FlagMessage, HelperHintIcon, KeyboardHint, LargeCenteredLayout, LightLabel, } from 'design-system'; import { difference, intersection } from 'lodash'; import * as React from 'react'; import { Helmet } from 'react-helmet-async'; import A11ySkipTarget from '../../../components/a11y/A11ySkipTarget'; import HelpTooltip from '../../../components/controls/HelpTooltip'; import ListFooter from '../../../components/controls/ListFooter'; import Suggestions from '../../../components/embed-docs-modal/Suggestions'; import { Location } from '../../../components/hoc/withRouter'; import AnalysisMissingInfoMessage from '../../../components/shared/AnalysisMissingInfoMessage'; import { CCT_SOFTWARE_QUALITY_METRICS, OLD_TAXONOMY_METRICS } from '../../../helpers/constants'; import { KeyboardKeys } from '../../../helpers/keycodes'; import { translate } from '../../../helpers/l10n'; import { areCCTMeasuresComputed } from '../../../helpers/measures'; import { BranchLike } from '../../../types/branch-like'; import { isApplication, isPortfolioLike } from '../../../types/component'; import { Breadcrumb, Component, ComponentMeasure, Dict, Metric } from '../../../types/types'; import { getCodeMetrics } from '../utils'; import CodeBreadcrumbs from './CodeBreadcrumbs'; import Components from './Components'; import Search from './Search'; import SourceViewerWrapper from './SourceViewerWrapper'; interface Props { branchLike?: BranchLike; component: Component; location: Location; metrics: Dict; baseComponent?: ComponentMeasure; breadcrumbs: Breadcrumb[]; components?: ComponentMeasure[]; highlighted?: ComponentMeasure; loading: boolean; searchResults?: ComponentMeasure[]; sourceViewer?: ComponentMeasure; total: number; newCodeSelected: boolean; handleGoToParent: () => void; handleHighlight: (highlighted: ComponentMeasure) => void; handleLoadMore: () => void; handleSearchClear: () => void; handleSearchResults: (searchResults: ComponentMeasure[]) => void; handleSelect: (component: ComponentMeasure) => void; handleSelectNewCode: (newCodeSelected: boolean) => void; } export default function CodeAppRenderer(props: Readonly) { const { branchLike, component, location, baseComponent, breadcrumbs, components = [], highlighted, loading, metrics, newCodeSelected, total, searchResults, sourceViewer, } = props; const { canBrowseAllChildProjects, qualifier } = component; const showSearch = searchResults !== undefined; const hasComponents = components.length > 0 || searchResults !== undefined; const showBreadcrumbs = breadcrumbs.length > 1 && !showSearch; const showComponentList = sourceViewer === undefined && components.length > 0 && !showSearch; const metricKeys = intersection( getCodeMetrics(component.qualifier, branchLike, { newCode: newCodeSelected }), Object.keys(metrics), ); const allComponentsHaveSoftwareQualityMeasures = components.every((component) => areCCTMeasuresComputed(component.measures), ); const filteredMetrics = difference( metricKeys, allComponentsHaveSoftwareQualityMeasures ? OLD_TAXONOMY_METRICS : CCT_SOFTWARE_QUALITY_METRICS, ).map((key) => metrics[key]); let defaultTitle = translate('code.page'); if (isApplication(baseComponent?.qualifier)) { defaultTitle = translate('projects.page'); } else if (isPortfolioLike(baseComponent?.qualifier)) { defaultTitle = translate('portfolio_breakdown.page'); } const isPortfolio = isPortfolioLike(qualifier); return ( {!canBrowseAllChildProjects && isPortfolio && ( {translate('code_viewer.not_all_measures_are_shown')} )} {!allComponentsHaveSoftwareQualityMeasures && ( )}
{hasComponents && ( )} {!hasComponents && sourceViewer === undefined && (
{translate( 'code_viewer.no_source_code_displayed_due_to_empty_analysis', component.qualifier, )}
)} {showBreadcrumbs && ( )}
{(showComponentList || showSearch) && (
)}
{(showComponentList || showSearch) && ( {showComponentList && ( )} {showSearch && ( )} )} {showComponentList && ( )} {sourceViewer !== undefined && !showSearch && (
)}
); }