@@ -20,7 +20,7 @@ | |||
import { BasicSeparator, FacetItem } from 'design-system'; | |||
import * as React from 'react'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import { MeasuresTabs } from '../../overview/utils'; | |||
import { CodeScope } from '../../../helpers/urls'; | |||
import { Query } from '../utils'; | |||
import { FacetItemsList } from './FacetItemsList'; | |||
@@ -56,7 +56,7 @@ export function PeriodFilter(props: PeriodFilterProps) { | |||
className="it__search-navigator-facet" | |||
name={translate('issues.new_code')} | |||
onClick={handleClick} | |||
value={newCodeSelected ? MeasuresTabs.New : MeasuresTabs.Overall} | |||
value={newCodeSelected ? CodeScope.New : CodeScope.Overall} | |||
/> | |||
<BasicSeparator className="sw-mb-5 sw-mt-4" /> |
@@ -27,7 +27,7 @@ import { | |||
import * as React from 'react'; | |||
import { useIntl } from 'react-intl'; | |||
import A11ySkipTarget from '../../../components/a11y/A11ySkipTarget'; | |||
import { useLocation } from '../../../components/hoc/withRouter'; | |||
import { useLocation, useRouter } from '../../../components/hoc/withRouter'; | |||
import { parseDate } from '../../../helpers/dates'; | |||
import { isDiffMetric } from '../../../helpers/measures'; | |||
import { CodeScope } from '../../../helpers/urls'; | |||
@@ -39,7 +39,6 @@ import { Analysis, GraphType, MeasureHistory } from '../../../types/project-acti | |||
import { QualityGateStatus } from '../../../types/quality-gates'; | |||
import { Component, MeasureEnhanced, Metric, Period, QualityGate } from '../../../types/types'; | |||
import { AnalysisStatus } from '../components/AnalysisStatus'; | |||
import { MeasuresTabs } from '../utils'; | |||
import ActivityPanel from './ActivityPanel'; | |||
import BranchMetaTopBar from './BranchMetaTopBar'; | |||
import FirstAnalysisNextStepsNotif from './FirstAnalysisNextStepsNotif'; | |||
@@ -93,13 +92,12 @@ export default function BranchOverviewRenderer(props: BranchOverviewRendererProp | |||
} = props; | |||
const { query } = useLocation(); | |||
const [tab, selectTab] = React.useState(() => { | |||
return query.codeScope === CodeScope.Overall ? MeasuresTabs.Overall : MeasuresTabs.New; | |||
}); | |||
const intl = useIntl(); | |||
const router = useRouter(); | |||
const intl = useIntl(); | |||
const tab = query.codeScope === CodeScope.Overall ? CodeScope.Overall : CodeScope.New; | |||
const leakPeriod = component.qualifier === ComponentQualifier.Application ? appLeak : period; | |||
const isNewCodeTab = tab === MeasuresTabs.New; | |||
const isNewCodeTab = tab === CodeScope.New; | |||
const hasNewCodeMeasures = measures.some((m) => isDiffMetric(m.metric.key)); | |||
// Check if any potentially missing uncomputed measure is not present | |||
@@ -109,10 +107,14 @@ export default function BranchOverviewRenderer(props: BranchOverviewRendererProp | |||
: [MetricKey.security_issues, MetricKey.maintainability_issues, MetricKey.reliability_issues] | |||
).some((key) => !measures.find((measure) => measure.metric.key === key)); | |||
const selectTab = (tab: CodeScope) => { | |||
router.replace({ query: { ...query, codeScope: tab } }); | |||
}; | |||
React.useEffect(() => { | |||
// Open Overall tab by default if there are no new measures. | |||
if (loadingStatus === false && !hasNewCodeMeasures && isNewCodeTab) { | |||
selectTab(MeasuresTabs.Overall); | |||
selectTab(CodeScope.Overall); | |||
} | |||
// In this case, we explicitly do NOT want to mark tab as a dependency, as | |||
// it would prevent the user from selecting it, even if it's empty. |
@@ -25,12 +25,11 @@ import { getTabPanelId } from '../../../components/controls/BoxedTabs'; | |||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import { getBaseUrl } from '../../../helpers/system'; | |||
import { queryToSearch } from '../../../helpers/urls'; | |||
import { CodeScope, queryToSearch } from '../../../helpers/urls'; | |||
import { Branch } from '../../../types/branch-like'; | |||
import { ComponentQualifier } from '../../../types/component'; | |||
import { NewCodeDefinitionType } from '../../../types/new-code-definition'; | |||
import { Component, Period } from '../../../types/types'; | |||
import { MeasuresTabs } from '../utils'; | |||
export interface MeasuresPanelNoNewCodeProps { | |||
branch?: Branch; | |||
@@ -64,7 +63,7 @@ export default function MeasuresPanelNoNewCode(props: MeasuresPanelNoNewCodeProp | |||
return ( | |||
<div | |||
className="display-flex-center display-flex-justify-center" | |||
id={getTabPanelId(MeasuresTabs.New)} | |||
id={getTabPanelId(CodeScope.New)} | |||
style={{ height: 500 }} | |||
> | |||
<img |
@@ -36,7 +36,11 @@ import { getLeakValue } from '../../../components/measure/utils'; | |||
import { DEFAULT_ISSUES_QUERY } from '../../../components/shared/utils'; | |||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||
import { findMeasure, formatMeasure, formatRating } from '../../../helpers/measures'; | |||
import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls'; | |||
import { | |||
CodeScope, | |||
getComponentIssuesUrl, | |||
getComponentSecurityHotspotsUrl, | |||
} from '../../../helpers/urls'; | |||
import { Branch } from '../../../types/branch-like'; | |||
import { isApplication } from '../../../types/component'; | |||
import { IssueStatus } from '../../../types/issues'; | |||
@@ -45,7 +49,7 @@ import { QualityGateStatus } from '../../../types/quality-gates'; | |||
import { Component, MeasureEnhanced } from '../../../types/types'; | |||
import { IssueMeasuresCardInner } from '../components/IssueMeasuresCardInner'; | |||
import MeasuresCardNumber from '../components/MeasuresCardNumber'; | |||
import { MeasuresTabs, Status, getConditionRequiredLabel } from '../utils'; | |||
import { Status, getConditionRequiredLabel } from '../utils'; | |||
import MeasuresPanelPercentCards from './MeasuresPanelPercentCards'; | |||
interface Props { | |||
@@ -107,7 +111,7 @@ export default function NewCodeMeasuresPanel(props: Readonly<Props>) { | |||
} | |||
return ( | |||
<div className="sw-grid sw-grid-cols-2 sw-gap-4 sw-mt-6" id={getTabPanelId(MeasuresTabs.New)}> | |||
<div className="sw-grid sw-grid-cols-2 sw-gap-4 sw-mt-6" id={getTabPanelId(CodeScope.New)}> | |||
<LightGreyCard className="sw-flex sw-col-span-2 sw-rounded-2 sw-gap-4"> | |||
<IssueMeasuresCardInner | |||
data-testid="overview__measures-new_issues" |
@@ -28,7 +28,11 @@ import * as React from 'react'; | |||
import { useIntl } from 'react-intl'; | |||
import { getBranchLikeQuery } from '../../../helpers/branch-like'; | |||
import { findMeasure, formatMeasure, formatRating } from '../../../helpers/measures'; | |||
import { getComponentIssuesUrl, getComponentSecurityHotspotsUrl } from '../../../helpers/urls'; | |||
import { | |||
CodeScope, | |||
getComponentIssuesUrl, | |||
getComponentSecurityHotspotsUrl, | |||
} from '../../../helpers/urls'; | |||
import { Branch } from '../../../types/branch-like'; | |||
import { SoftwareQuality } from '../../../types/clean-code-taxonomy'; | |||
import { isApplication } from '../../../types/component'; | |||
@@ -39,7 +43,6 @@ import { Component, MeasureEnhanced } from '../../../types/types'; | |||
import MeasuresCard from '../components/MeasuresCard'; | |||
import MeasuresCardNumber from '../components/MeasuresCardNumber'; | |||
import { OverviewDisabledLinkTooltip } from '../components/OverviewDisabledLinkTooltip'; | |||
import { MeasuresTabs } from '../utils'; | |||
import MeasuresPanelPercentCards from './MeasuresPanelPercentCards'; | |||
import SoftwareImpactMeasureCard from './SoftwareImpactMeasureCard'; | |||
@@ -62,7 +65,7 @@ export default function OverallCodeMeasuresPanel(props: Readonly<OverallCodeMeas | |||
const securityRating = findMeasure(measures, MetricKey.security_review_rating)?.value; | |||
return ( | |||
<div id={getTabPanelId(MeasuresTabs.Overall)} className="sw-mt-6"> | |||
<div id={getTabPanelId(CodeScope.Overall)} className="sw-mt-6"> | |||
<div className="sw-flex sw-gap-4"> | |||
<SoftwareImpactMeasureCard | |||
branch={branch} |
@@ -32,6 +32,7 @@ import { FormattedMessage } from 'react-intl'; | |||
import DocLink from '../../../components/common/DocLink'; | |||
import { translate } from '../../../helpers/l10n'; | |||
import { isDiffMetric } from '../../../helpers/measures'; | |||
import { CodeScope } from '../../../helpers/urls'; | |||
import { ApplicationPeriod } from '../../../types/application'; | |||
import { Branch } from '../../../types/branch-like'; | |||
import { ComponentQualifier } from '../../../types/component'; | |||
@@ -39,7 +40,6 @@ import { Analysis, ProjectAnalysisEventCategory } from '../../../types/project-a | |||
import { QualityGateStatus } from '../../../types/quality-gates'; | |||
import { Component, Period } from '../../../types/types'; | |||
import LastAnalysisLabel from '../components/LastAnalysisLabel'; | |||
import { MeasuresTabs } from '../utils'; | |||
import { MAX_ANALYSES_NB } from './ActivityPanel'; | |||
import { LeakPeriodInfo } from './LeakPeriodInfo'; | |||
@@ -52,7 +52,7 @@ export interface MeasuresPanelProps { | |||
branch?: Branch; | |||
qgStatuses?: QualityGateStatus[]; | |||
isNewCode: boolean; | |||
onTabSelect: (tab: MeasuresTabs) => void; | |||
onTabSelect: (tab: CodeScope) => void; | |||
} | |||
const SQ_UPGRADE_NOTIFICATION_TIMEOUT = { weeks: 3 }; | |||
@@ -118,12 +118,12 @@ export function TabsPanel(props: React.PropsWithChildren<MeasuresPanelProps>) { | |||
const tabs = [ | |||
{ | |||
value: MeasuresTabs.New, | |||
value: CodeScope.New, | |||
label: translate('overview.new_code'), | |||
counter: failingConditionsOnNewCode, | |||
}, | |||
{ | |||
value: MeasuresTabs.Overall, | |||
value: CodeScope.Overall, | |||
label: translate('overview.overall_code'), | |||
counter: failingConditionsOnOverallCode, | |||
}, | |||
@@ -165,7 +165,7 @@ export function TabsPanel(props: React.PropsWithChildren<MeasuresPanelProps>) { | |||
<Tabs | |||
onChange={props.onTabSelect} | |||
options={tabs} | |||
value={isNewCode ? MeasuresTabs.New : MeasuresTabs.Overall} | |||
value={isNewCode ? CodeScope.New : CodeScope.Overall} | |||
> | |||
{isNewCode && leakPeriod && ( | |||
<LightLabel className="sw-body-sm sw-flex sw-items-center sw-mr-6"> |
@@ -131,11 +131,6 @@ const MEASURES_VARIATIONS_METRICS = [ | |||
MetricKey.vulnerabilities, | |||
]; | |||
export enum MeasuresTabs { | |||
New = 'new', | |||
Overall = 'overall', | |||
} | |||
export enum MeasurementType { | |||
Coverage = 'COVERAGE', | |||
Duplication = 'DUPLICATION', |