/* * 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 styled from '@emotion/styled'; import { Link, LinkStandalone } from '@sonarsource/echoes-react'; import classNames from 'classnames'; import { Badge, Card, LightLabel, LightPrimary, Note, QualityGateIndicator, SeparatorCircleIcon, SubnavigationFlowSeparator, Tags, themeBorder, themeColor, } from 'design-system'; import { isEmpty } from 'lodash'; import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import Favorite from '../../../../components/controls/Favorite'; import Tooltip from '../../../../components/controls/Tooltip'; import DateFromNow from '../../../../components/intl/DateFromNow'; import DateTimeFormatter from '../../../../components/intl/DateTimeFormatter'; import Measure from '../../../../components/measure/Measure'; import { translate, translateWithParameters } from '../../../../helpers/l10n'; import { formatMeasure } from '../../../../helpers/measures'; import { isDefined } from '../../../../helpers/types'; import { getProjectUrl } from '../../../../helpers/urls'; import { ComponentQualifier } from '../../../../types/component'; import { MetricKey, MetricType } from '../../../../types/metrics'; import { Status } from '../../../../types/types'; import { CurrentUser, isLoggedIn } from '../../../../types/users'; import { Project } from '../../types'; import ProjectCardLanguages from './ProjectCardLanguages'; import ProjectCardMeasures from './ProjectCardMeasures'; interface Props { currentUser: CurrentUser; handleFavorite: (component: string, isFavorite: boolean) => void; project: Project; type?: string; } function renderFirstLine( project: Props['project'], handleFavorite: Props['handleFavorite'], isNewCode: boolean, ) { const { analysisDate, isFavorite, key, measures, name, qualifier, tags, visibility } = project; const awaitingScan = [ MetricKey.reliability_issues, MetricKey.maintainability_issues, MetricKey.security_issues, ].every((key) => measures[key] === undefined) && !isNewCode && !isEmpty(analysisDate) && measures.ncloc !== undefined; const formatted = formatMeasure(measures[MetricKey.alert_status], MetricType.Level); const qualityGateLabel = translateWithParameters('overview.quality_gate_x', formatted); return ( <>