aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web
diff options
context:
space:
mode:
authorPhilippe Perrin <philippe.perrin@sonarsource.com>2023-06-08 10:22:27 +0200
committersonartech <sonartech@sonarsource.com>2023-06-26 20:03:54 +0000
commitdf412e40611054143f326a2d364028b64f4a8bac (patch)
treedfe66bcdbde70544f68e26ee2c45a407108cd35f /server/sonar-web
parent50324c4ab7e55dfd8293dd9ac21afe751ac7e345 (diff)
downloadsonarqube-df412e40611054143f326a2d364028b64f4a8bac.tar.gz
sonarqube-df412e40611054143f326a2d364028b64f4a8bac.zip
SONAR-19687 Non-compliant global new code definition value should not be proposed as default
Diffstat (limited to 'server/sonar-web')
-rw-r--r--server/sonar-web/src/main/js/api/mocks/NewCodePeriodsServiceMock.ts25
-rw-r--r--server/sonar-web/src/main/js/api/newCodePeriod.ts12
-rw-r--r--server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx10
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx16
-rw-r--r--server/sonar-web/src/main/js/apps/create/project/types.ts4
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx4
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx15
-rw-r--r--server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx5
-rw-r--r--server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx11
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingAnalysis.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx6
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx70
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/BranchList.tsx18
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/BranchListRow.tsx22
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineApp.tsx42
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx28
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx12
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts44
-rw-r--r--server/sonar-web/src/main/js/apps/projectBaseline/utils.ts27
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/NewCodePeriod.tsx58
-rw-r--r--server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx4
-rw-r--r--server/sonar-web/src/main/js/components/new-code-definition/GlobalNewCodeDefinitionDescription.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx15
-rw-r--r--server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionPreviousVersionOption.tsx6
-rw-r--r--server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx79
-rw-r--r--server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionWarning.tsx10
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/new-code-definition-test.ts84
-rw-r--r--server/sonar-web/src/main/js/helpers/__tests__/new-code-period-test.ts (renamed from server/sonar-web/src/main/js/helpers/__tests__/periods-test.ts)72
-rw-r--r--server/sonar-web/src/main/js/helpers/mocks/new-code-definition.ts (renamed from server/sonar-web/src/main/js/helpers/mocks/new-code-period.ts)14
-rw-r--r--server/sonar-web/src/main/js/helpers/new-code-definition.ts70
-rw-r--r--server/sonar-web/src/main/js/helpers/new-code-period.ts (renamed from server/sonar-web/src/main/js/helpers/periods.ts)45
-rw-r--r--server/sonar-web/src/main/js/types/branch-like.ts5
-rw-r--r--server/sonar-web/src/main/js/types/new-code-definition.ts (renamed from server/sonar-web/src/main/js/apps/projectBaseline/constants.ts)27
-rw-r--r--server/sonar-web/src/main/js/types/types.ts29
36 files changed, 540 insertions, 377 deletions
diff --git a/server/sonar-web/src/main/js/api/mocks/NewCodePeriodsServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/NewCodePeriodsServiceMock.ts
index 0e8506433de..0d429a7af6a 100644
--- a/server/sonar-web/src/main/js/api/mocks/NewCodePeriodsServiceMock.ts
+++ b/server/sonar-web/src/main/js/api/mocks/NewCodePeriodsServiceMock.ts
@@ -18,8 +18,15 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { cloneDeep } from 'lodash';
-import { mockNewCodePeriod, mockNewCodePeriodBranch } from '../../helpers/mocks/new-code-period';
-import { NewCodePeriod, NewCodePeriodBranch, NewCodePeriodSettingType } from '../../types/types';
+import {
+ mockNewCodePeriod,
+ mockNewCodePeriodBranch,
+} from '../../helpers/mocks/new-code-definition';
+import {
+ NewCodeDefinition,
+ NewCodeDefinitionBranch,
+ NewCodeDefinitionType,
+} from '../../types/new-code-definition';
import {
getNewCodePeriod,
listBranchesNewCodePeriod,
@@ -34,13 +41,13 @@ export default class NewCodePeriodsServiceMock {
mockNewCodePeriodBranch({ inherited: true, branchKey: 'main' }),
mockNewCodePeriodBranch({
branchKey: 'feature',
- type: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ type: NewCodeDefinitionType.NumberOfDays,
value: '1',
}),
];
- #newCodePeriod: NewCodePeriod;
- #listBranchesNewCode: NewCodePeriodBranch[];
+ #newCodePeriod: NewCodeDefinition;
+ #listBranchesNewCode: NewCodeDefinitionBranch[];
constructor() {
this.#newCodePeriod = cloneDeep(this.#defaultNewCodePeriod);
@@ -58,14 +65,14 @@ export default class NewCodePeriodsServiceMock {
handleSetNewCodePeriod = (data: {
project?: string;
branch?: string;
- type: NewCodePeriodSettingType;
+ type: NewCodeDefinitionType;
value?: string;
}) => {
const { type, value, branch } = data;
if (branch) {
const branchNewCode = this.#listBranchesNewCode.find(
(bNew) => bNew.branchKey === branch
- ) as NewCodePeriodBranch;
+ ) as NewCodeDefinitionBranch;
branchNewCode.type = type;
branchNewCode.value = value;
} else {
@@ -93,11 +100,11 @@ export default class NewCodePeriodsServiceMock {
return this.reply({ newCodePeriods: this.#listBranchesNewCode });
};
- setNewCodePeriod = (newCodePeriod: NewCodePeriod) => {
+ setNewCodePeriod = (newCodePeriod: NewCodeDefinition) => {
this.#newCodePeriod = newCodePeriod;
};
- setListBranchesNewCode = (listBranchesNewCode: NewCodePeriodBranch[]) => {
+ setListBranchesNewCode = (listBranchesNewCode: NewCodeDefinitionBranch[]) => {
this.#listBranchesNewCode = listBranchesNewCode;
};
diff --git a/server/sonar-web/src/main/js/api/newCodePeriod.ts b/server/sonar-web/src/main/js/api/newCodePeriod.ts
index b930d715ef2..ca56e5f17ea 100644
--- a/server/sonar-web/src/main/js/api/newCodePeriod.ts
+++ b/server/sonar-web/src/main/js/api/newCodePeriod.ts
@@ -19,19 +19,23 @@
*/
import { throwGlobalError } from '../helpers/error';
import { getJSON, post } from '../helpers/request';
-import { NewCodePeriod, NewCodePeriodBranch, NewCodePeriodSettingType } from '../types/types';
+import {
+ NewCodeDefinition,
+ NewCodeDefinitionBranch,
+ NewCodeDefinitionType,
+} from '../types/new-code-definition';
export function getNewCodePeriod(data?: {
project?: string;
branch?: string;
-}): Promise<Omit<NewCodePeriod, 'effectiveValue'>> {
+}): Promise<Omit<NewCodeDefinition, 'effectiveValue'>> {
return getJSON('/api/new_code_periods/show', data).catch(throwGlobalError);
}
export function setNewCodePeriod(data: {
project?: string;
branch?: string;
- type: NewCodePeriodSettingType;
+ type: NewCodeDefinitionType;
value?: string;
}): Promise<void> {
return post('/api/new_code_periods/set', data).catch(throwGlobalError);
@@ -43,6 +47,6 @@ export function resetNewCodePeriod(data: { project?: string; branch?: string }):
export function listBranchesNewCodePeriod(data: {
project: string;
-}): Promise<{ newCodePeriods: NewCodePeriodBranch[] }> {
+}): Promise<{ newCodePeriods: NewCodeDefinitionBranch[] }> {
return getJSON('/api/new_code_periods/list', data).catch(throwGlobalError);
}
diff --git a/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx b/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx
index 93bd5e6911c..dc2b236b822 100644
--- a/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx
+++ b/server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx
@@ -27,9 +27,10 @@ import DateFormatter, { longFormatterOption } from '../../../components/intl/Dat
import DateFromNow from '../../../components/intl/DateFromNow';
import DateTimeFormatter, { formatterOption } from '../../../components/intl/DateTimeFormatter';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { getPeriodDate, getPeriodLabel } from '../../../helpers/periods';
+import { getNewCodePeriodDate, getNewCodePeriodLabel } from '../../../helpers/new-code-period';
import { ComponentQualifier } from '../../../types/component';
-import { ComponentMeasure, NewCodePeriodSettingType, Period } from '../../../types/types';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
+import { ComponentMeasure, Period } from '../../../types/types';
export interface LeakPeriodLegendProps {
component: ComponentMeasure;
@@ -56,7 +57,7 @@ class LeakPeriodLegend extends React.PureComponent<LeakPeriodLegendProps & Wrapp
);
}
- const leakPeriodLabel = getPeriodLabel(
+ const leakPeriodLabel = getNewCodePeriodLabel(
period,
period.mode === 'manual_baseline' ? this.formatDateTime : this.formatDate
);
@@ -68,11 +69,11 @@ class LeakPeriodLegend extends React.PureComponent<LeakPeriodLegendProps & Wrapp
</LeakPeriodLabel>
);
- if (period.mode === 'days' || period.mode === NewCodePeriodSettingType.NUMBER_OF_DAYS) {
+ if (period.mode === 'days' || period.mode === NewCodeDefinitionType.NumberOfDays) {
return label;
}
- const date = getPeriodDate(period);
+ const date = getNewCodePeriodDate(period);
const tooltip = date && (
<div>
<DateFromNow date={date} />
diff --git a/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx b/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
index 7b2abaa73dd..1238d1e05dd 100644
--- a/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
@@ -17,6 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import classNames from 'classnames';
import * as React from 'react';
import { Helmet } from 'react-helmet-async';
import { FormattedMessage } from 'react-intl';
@@ -31,12 +32,13 @@ import { ButtonLink, SubmitButton } from '../../../components/controls/buttons';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
import NewCodeDefinitionSelector from '../../../components/new-code-definition/NewCodeDefinitionSelector';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
+import { addGlobalSuccessMessage } from '../../../helpers/globalMessages';
import { translate } from '../../../helpers/l10n';
import { getProjectUrl } from '../../../helpers/urls';
import { AlmKeys, AlmSettingsInstance } from '../../../types/alm-settings';
import { AppState } from '../../../types/appstate';
import { Feature } from '../../../types/features';
-import { NewCodePeriodWithCompliance } from '../../../types/types';
+import { NewCodeDefinitiondWithCompliance } from '../../../types/new-code-definition';
import AlmBindingDefinitionForm from '../../settings/components/almIntegration/AlmBindingDefinitionForm';
import AzureProjectCreate from './Azure/AzureProjectCreate';
import BitbucketCloudProjectCreate from './BitbucketCloud/BitbucketCloudProjectCreate';
@@ -48,8 +50,6 @@ import CreateProjectPageHeader from './components/CreateProjectPageHeader';
import ManualProjectCreate from './manual/ManualProjectCreate';
import './style.css';
import { CreateProjectApiCallback, CreateProjectModes } from './types';
-import { addGlobalSuccessMessage } from '../../../helpers/globalMessages';
-import classNames from 'classnames';
export interface CreateProjectPageProps extends WithAvailableFeaturesProps {
appState: AppState;
@@ -66,7 +66,7 @@ interface State {
loading: boolean;
isProjectSetupDone: boolean;
creatingAlmDefinition?: AlmKeys;
- selectedNcd: NewCodePeriodWithCompliance | null;
+ selectedNcd: NewCodeDefinitiondWithCompliance | null;
submitting: boolean;
}
@@ -177,7 +177,7 @@ export class CreateProjectPage extends React.PureComponent<CreateProjectPageProp
}
};
- handleNcdChanged = (ncd: NewCodePeriodWithCompliance) => {
+ handleNcdChanged = (ncd: NewCodeDefinitiondWithCompliance) => {
this.setState({
selectedNcd: ncd,
});
diff --git a/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx b/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx
index daffdc75925..1b22f0b085f 100644
--- a/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx
+++ b/server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx
@@ -27,7 +27,7 @@ import { mockProject } from '../../../../helpers/mocks/projects';
import { mockAppState } from '../../../../helpers/testMocks';
import { renderApp } from '../../../../helpers/testReactTestingUtils';
import { byRole, byText } from '../../../../helpers/testSelector';
-import { NewCodePeriodSettingType } from '../../../../types/types';
+import { NewCodeDefinitionType } from '../../../../types/new-code-definition';
import CreateProjectPage, { CreateProjectPageProps } from '../CreateProjectPage';
jest.mock('../../../../api/alm-settings');
@@ -124,7 +124,7 @@ it('should fill form and move to NCD selection and back', async () => {
it('should select the global NCD when it is compliant', async () => {
jest
.mocked(getNewCodePeriod)
- .mockResolvedValue({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '30' });
+ .mockResolvedValue({ type: NewCodeDefinitionType.NumberOfDays, value: '30' });
const user = userEvent.setup();
renderCreateProject();
await fillFormAndNext('test', user);
@@ -142,7 +142,7 @@ it('should select the global NCD when it is compliant', async () => {
it('global NCD option should be disabled if not compliant', async () => {
jest
.mocked(getNewCodePeriod)
- .mockResolvedValue({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '96' });
+ .mockResolvedValue({ type: NewCodeDefinitionType.NumberOfDays, value: '96' });
const user = userEvent.setup();
renderCreateProject();
await fillFormAndNext('test', user);
@@ -161,7 +161,7 @@ it.each([
async ({ canAdmin, message }) => {
jest
.mocked(getNewCodePeriod)
- .mockResolvedValue({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '96' });
+ .mockResolvedValue({ type: NewCodeDefinitionType.NumberOfDays, value: '96' });
const user = userEvent.setup();
renderCreateProject({ appState: mockAppState({ canAdmin }) });
await fillFormAndNext('test', user);
@@ -175,7 +175,7 @@ it.each([ui.ncdOptionRefBranchRadio, ui.ncdOptionPreviousVersionRadio])(
async (option) => {
jest
.mocked(getNewCodePeriod)
- .mockResolvedValue({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '96' });
+ .mockResolvedValue({ type: NewCodeDefinitionType.NumberOfDays, value: '96' });
const user = userEvent.setup();
renderCreateProject();
await fillFormAndNext('test', user);
@@ -199,7 +199,7 @@ it.each([ui.ncdOptionRefBranchRadio, ui.ncdOptionPreviousVersionRadio])(
it('number of days should show error message if value is not a number', async () => {
jest
.mocked(getNewCodePeriod)
- .mockResolvedValue({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '60' });
+ .mockResolvedValue({ type: NewCodeDefinitionType.NumberOfDays, value: '60' });
const user = userEvent.setup();
renderCreateProject();
await fillFormAndNext('test', user);
@@ -214,7 +214,7 @@ it('number of days should show error message if value is not a number', async ()
await user.click(ui.ncdOptionDaysRadio.get());
expect(ui.ncdOptionDaysInput.get()).toBeInTheDocument();
- expect(ui.ncdOptionDaysInput.get()).toHaveValue('30');
+ expect(ui.ncdOptionDaysInput.get()).toHaveValue('60');
expect(ui.projectCreateButton.get()).toBeEnabled();
await user.click(ui.ncdOptionDaysInput.get());
@@ -232,7 +232,7 @@ it('number of days should show error message if value is not a number', async ()
});
it('the project onboarding page should be displayed when the project is created', async () => {
- newCodePeriodHandler.setNewCodePeriod({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS });
+ newCodePeriodHandler.setNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays });
const user = userEvent.setup();
renderCreateProject();
await fillFormAndNext('testing', user);
diff --git a/server/sonar-web/src/main/js/apps/create/project/types.ts b/server/sonar-web/src/main/js/apps/create/project/types.ts
index ddd7c3700a4..6b578e4705e 100644
--- a/server/sonar-web/src/main/js/apps/create/project/types.ts
+++ b/server/sonar-web/src/main/js/apps/create/project/types.ts
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { ProjectBase } from '../../../api/components';
-import { NewCodePeriodSettingType } from '../../../types/types';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
export enum CreateProjectModes {
Manual = 'manual',
@@ -30,6 +30,6 @@ export enum CreateProjectModes {
}
export type CreateProjectApiCallback = (
- newCodeDefinitionType?: NewCodePeriodSettingType,
+ newCodeDefinitionType?: NewCodeDefinitionType,
newCodeDefinitionValue?: string
) => Promise<{ project: ProjectBase }>;
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx b/server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx
index 533cf15b074..daf24ee685c 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx
@@ -18,7 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { isApplicationPeriod } from '../../../helpers/periods';
+import { isApplicationNewCodePeriod } from '../../../helpers/new-code-period';
import { ApplicationPeriod } from '../../../types/application';
import { Period } from '../../../types/types';
import ApplicationLeakPeriodInfo from './ApplicationLeakPeriodInfo';
@@ -29,7 +29,7 @@ export interface LeakPeriodInfoProps {
}
export function LeakPeriodInfo({ leakPeriod }: LeakPeriodInfoProps) {
- if (isApplicationPeriod(leakPeriod)) {
+ if (isApplicationNewCodePeriod(leakPeriod)) {
return <ApplicationLeakPeriodInfo leakPeriod={leakPeriod} />;
}
return <ProjectLeakPeriodInfo leakPeriod={leakPeriod} />;
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx
index 37d8c2ac37f..fad0d415731 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx
@@ -27,7 +27,8 @@ import { getBaseUrl } from '../../../helpers/system';
import { queryToSearch } from '../../../helpers/urls';
import { Branch } from '../../../types/branch-like';
import { ComponentQualifier } from '../../../types/component';
-import { Component, NewCodePeriodSettingType, Period } from '../../../types/types';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
+import { Component, Period } from '../../../types/types';
export interface MeasuresPanelNoNewCodeProps {
branch?: Branch;
@@ -41,7 +42,7 @@ export default function MeasuresPanelNoNewCode(props: MeasuresPanelNoNewCodeProp
const isApp = component.qualifier === ComponentQualifier.Application;
const hasBadReferenceBranch =
- !isApp && !!period && !period.date && period.mode === NewCodePeriodSettingType.REFERENCE_BRANCH;
+ !isApp && !!period && !period.date && period.mode === NewCodeDefinitionType.ReferenceBranch;
/*
* If the period is "reference branch"-based, and if there's no date, it means
* that we're not lacking a second analysis, but that we'll never have new code because the
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx b/server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx
index 4a9025ba54c..ff14b007ff1 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx
@@ -23,8 +23,9 @@ import { longFormatterOption } from '../../../components/intl/DateFormatter';
import DateFromNow from '../../../components/intl/DateFromNow';
import { formatterOption } from '../../../components/intl/DateTimeFormatter';
import { translateWithParameters } from '../../../helpers/l10n';
-import { getPeriodDate, getPeriodLabel } from '../../../helpers/periods';
-import { NewCodePeriodSettingType, Period } from '../../../types/types';
+import { getNewCodePeriodDate, getNewCodePeriodLabel } from '../../../helpers/new-code-period';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
+import { Period } from '../../../types/types';
export interface ProjectLeakPeriodInfoProps extends WrappedComponentProps {
leakPeriod: Period;
@@ -36,9 +37,9 @@ export function ProjectLeakPeriodInfo(props: ProjectLeakPeriodInfoProps) {
leakPeriod,
} = props;
- const leakPeriodLabel = getPeriodLabel(
+ const leakPeriodLabel = getNewCodePeriodLabel(
leakPeriod,
- ['manual_baseline', NewCodePeriodSettingType.SPECIFIC_ANALYSIS].includes(leakPeriod.mode)
+ ['manual_baseline', NewCodeDefinitionType.SpecificAnalysis].includes(leakPeriod.mode)
? (date: string) => formatTime(date, formatterOption)
: (date: string) => formatDate(date, longFormatterOption)
);
@@ -49,13 +50,13 @@ export function ProjectLeakPeriodInfo(props: ProjectLeakPeriodInfoProps) {
if (
leakPeriod.mode === 'days' ||
- leakPeriod.mode === NewCodePeriodSettingType.NUMBER_OF_DAYS ||
- leakPeriod.mode === NewCodePeriodSettingType.REFERENCE_BRANCH
+ leakPeriod.mode === NewCodeDefinitionType.NumberOfDays ||
+ leakPeriod.mode === NewCodeDefinitionType.ReferenceBranch
) {
return <div>{leakPeriodLabel} </div>;
}
- const leakPeriodDate = getPeriodDate(leakPeriod);
+ const leakPeriodDate = getNewCodePeriodDate(leakPeriod);
if (!leakPeriodDate) {
return null;
diff --git a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx
index 516922ab183..e03094a7ac9 100644
--- a/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx
@@ -23,7 +23,8 @@ import * as React from 'react';
import { IntlShape } from 'react-intl';
import { mockPeriod } from '../../../../helpers/testMocks';
import { renderComponent } from '../../../../helpers/testReactTestingUtils';
-import { NewCodePeriodSettingType, Period } from '../../../../types/types';
+import { NewCodeDefinitionType } from '../../../../types/new-code-definition';
+import { Period } from '../../../../types/types';
import { ProjectLeakPeriodInfo } from '../ProjectLeakPeriodInfo';
jest.mock('date-fns', () => {
@@ -62,7 +63,7 @@ it('should render correctly for "previous_analysis"', async () => {
it('should render correctly for "REFERENCE_BRANCH"', async () => {
renderProjectLeakPeriodInfo({
- mode: NewCodePeriodSettingType.REFERENCE_BRANCH,
+ mode: NewCodeDefinitionType.ReferenceBranch,
parameter: 'master',
});
expect(await screen.findByText('overview.period.reference_branch.master')).toBeInTheDocument();
diff --git a/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx b/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx
index 3209b00b9b2..a6076b28690 100644
--- a/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx
+++ b/server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx
@@ -25,8 +25,9 @@ import DateFormatter, { longFormatterOption } from '../../../components/intl/Dat
import DateFromNow from '../../../components/intl/DateFromNow';
import DateTimeFormatter, { formatterOption } from '../../../components/intl/DateTimeFormatter';
import { translateWithParameters } from '../../../helpers/l10n';
-import { getPeriodDate, getPeriodLabel } from '../../../helpers/periods';
-import { Dict, NewCodePeriodSettingType, Period } from '../../../types/types';
+import { getNewCodePeriodDate, getNewCodePeriodLabel } from '../../../helpers/new-code-period';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
+import { Dict, Period } from '../../../types/types';
interface Props {
period: Period;
@@ -48,7 +49,7 @@ export class LeakPeriodLegend extends React.PureComponent<Props & WrappedCompone
render() {
const { period } = this.props;
- const leakPeriodLabel = getPeriodLabel(
+ const leakPeriodLabel = getNewCodePeriodLabel(
period,
MODE_INCLUDES_TIME[period.mode] ? this.formatDateTime : this.formatDate
);
@@ -56,7 +57,7 @@ export class LeakPeriodLegend extends React.PureComponent<Props & WrappedCompone
return null;
}
- if (period.mode === 'days' || period.mode === NewCodePeriodSettingType.NUMBER_OF_DAYS) {
+ if (period.mode === 'days' || period.mode === NewCodeDefinitionType.NumberOfDays) {
return (
<div className="overview-legend overview-legend-spaced-line">
{translateWithParameters('overview.new_code_period_x', leakPeriodLabel)}
@@ -64,7 +65,7 @@ export class LeakPeriodLegend extends React.PureComponent<Props & WrappedCompone
);
}
- const leakPeriodDate = getPeriodDate(period);
+ const leakPeriodDate = getNewCodePeriodDate(period);
if (!leakPeriodDate) {
return null;
}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingAnalysis.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingAnalysis.tsx
index ca5db89b7e0..d042123ca89 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingAnalysis.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingAnalysis.tsx
@@ -20,10 +20,10 @@
import * as React from 'react';
import RadioCard from '../../../components/controls/RadioCard';
import { translate } from '../../../helpers/l10n';
-import { NewCodePeriodSettingType } from '../../../types/types';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
export interface Props {
- onSelect: (selection: NewCodePeriodSettingType) => void;
+ onSelect: (selection: NewCodeDefinitionType) => void;
selected: boolean;
}
@@ -32,7 +32,7 @@ export default function BaselineSettingAnalysis({ onSelect, selected }: Props) {
<RadioCard
noRadio
disabled
- onClick={() => onSelect(NewCodePeriodSettingType.SPECIFIC_ANALYSIS)}
+ onClick={() => onSelect(NewCodeDefinitionType.SpecificAnalysis)}
selected={selected}
title={translate('baseline.specific_analysis')}
>
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx
index adf4c56df1b..4e9b28484af 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx
@@ -26,14 +26,14 @@ import AlertErrorIcon from '../../../components/icons/AlertErrorIcon';
import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker';
import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { NewCodePeriodSettingType } from '../../../types/types';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
export interface BaselineSettingReferenceBranchProps {
branchList: BranchOption[];
className?: string;
disabled?: boolean;
onChangeReferenceBranch: (value: string) => void;
- onSelect: (selection: NewCodePeriodSettingType) => void;
+ onSelect: (selection: NewCodeDefinitionType) => void;
referenceBranch: string;
selected: boolean;
settingLevel: 'project' | 'branch';
@@ -98,7 +98,7 @@ export default function BaselineSettingReferenceBranch(props: BaselineSettingRef
noRadio
className={className}
disabled={disabled}
- onClick={() => props.onSelect(NewCodePeriodSettingType.REFERENCE_BRANCH)}
+ onClick={() => props.onSelect(NewCodeDefinitionType.ReferenceBranch)}
selected={selected}
title={translate('baseline.reference_branch')}
>
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx
index c60deb34b08..063a19f0639 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx
@@ -19,17 +19,18 @@
*/
import * as React from 'react';
import { setNewCodePeriod } from '../../../api/newCodePeriod';
-import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import Modal from '../../../components/controls/Modal';
+import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import NewCodeDefinitionDaysOption from '../../../components/new-code-definition/NewCodeDefinitionDaysOption';
import NewCodeDefinitionPreviousVersionOption from '../../../components/new-code-definition/NewCodeDefinitionPreviousVersionOption';
import NewCodeDefinitionWarning from '../../../components/new-code-definition/NewCodeDefinitionWarning';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { toISO8601WithOffsetString } from '../../../helpers/dates';
import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { getNumberOfDaysDefaultValue } from '../../../helpers/new-code-definition';
import { Branch, BranchWithNewCodePeriod } from '../../../types/branch-like';
+import { NewCodeDefinition, NewCodeDefinitionType } from '../../../types/new-code-definition';
import { ParsedAnalysis } from '../../../types/project-activity';
-import { NewCodePeriod, NewCodePeriodSettingType } from '../../../types/types';
import { getSettingValue, validateSetting } from '../utils';
import BaselineSettingAnalysis from './BaselineSettingAnalysis';
import BaselineSettingReferenceBranch from './BaselineSettingReferenceBranch';
@@ -39,7 +40,9 @@ interface Props {
branch: BranchWithNewCodePeriod;
branchList: Branch[];
component: string;
- onClose: (branch?: string, newSetting?: NewCodePeriod) => void;
+ onClose: (branch?: string, newSetting?: NewCodeDefinition) => void;
+ inheritedSetting: NewCodeDefinition;
+ generalSetting: NewCodeDefinition;
}
interface State {
@@ -48,7 +51,7 @@ interface State {
days: string;
referenceBranch: string;
saving: boolean;
- selected?: NewCodePeriodSettingType;
+ selected?: NewCodeDefinitionType;
}
export default class BranchBaselineSettingModal extends React.PureComponent<Props, State> {
@@ -57,16 +60,19 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
constructor(props: Props) {
super(props);
- const otherBranches = props.branchList.filter((b) => b.name !== props.branch.name);
+ const { branch, branchList, inheritedSetting, generalSetting } = props;
+ const otherBranches = branchList.filter((b) => b.name !== branch.name);
const defaultBranch = otherBranches.length > 0 ? otherBranches[0].name : '';
this.state = {
- analysis: this.getValueFromProps(NewCodePeriodSettingType.SPECIFIC_ANALYSIS) || '',
- days: this.getValueFromProps(NewCodePeriodSettingType.NUMBER_OF_DAYS) || '30',
+ analysis: this.getValueFromProps(NewCodeDefinitionType.SpecificAnalysis) || '',
+ days:
+ this.getValueFromProps(NewCodeDefinitionType.NumberOfDays) ||
+ getNumberOfDaysDefaultValue(generalSetting, inheritedSetting),
referenceBranch:
- this.getValueFromProps(NewCodePeriodSettingType.REFERENCE_BRANCH) || defaultBranch,
+ this.getValueFromProps(NewCodeDefinitionType.ReferenceBranch) || defaultBranch,
saving: false,
- selected: this.props.branch.newCodePeriod && this.props.branch.newCodePeriod.type,
+ selected: branch.newCodePeriod?.type,
};
}
@@ -78,7 +84,7 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
this.mounted = false;
}
- getValueFromProps(type: NewCodePeriodSettingType) {
+ getValueFromProps(type: NewCodeDefinitionType) {
return this.props.branch.newCodePeriod && this.props.branch.newCodePeriod.type === type
? this.props.branch.newCodePeriod.value
: null;
@@ -108,19 +114,23 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
branch: branch.name,
}).then(
() => {
- this.setState({
- saving: false,
- });
- this.props.onClose(branch.name, {
- type,
- value,
- effectiveValue: analysisDate && toISO8601WithOffsetString(analysisDate),
- });
+ if (this.mounted) {
+ this.setState({
+ saving: false,
+ });
+ this.props.onClose(branch.name, {
+ type,
+ value,
+ effectiveValue: analysisDate && toISO8601WithOffsetString(analysisDate),
+ });
+ }
},
() => {
- this.setState({
- saving: false,
- });
+ if (this.mounted) {
+ this.setState({
+ saving: false,
+ });
+ }
}
);
}
@@ -135,7 +145,7 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
handleSelectReferenceBranch = (referenceBranch: string) => this.setState({ referenceBranch });
- handleSelectSetting = (selected: NewCodePeriodSettingType) => this.setState({ selected });
+ handleSelectSetting = (selected: NewCodeDefinitionType) => this.setState({ selected });
render() {
const { branch, branchList } = this.props;
@@ -143,8 +153,8 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
const header = translateWithParameters('baseline.new_code_period_for_branch_x', branch.name);
- const currentSetting = branch.newCodePeriod && branch.newCodePeriod.type;
- const currentSettingValue = branch.newCodePeriod && branch.newCodePeriod.value;
+ const currentSetting = branch.newCodePeriod?.type;
+ const currentSettingValue = branch.newCodePeriod?.value;
const { isChanged, isValid } = validateSetting({
analysis,
@@ -173,7 +183,7 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
<NewCodeDefinitionPreviousVersionOption
isDefault={false}
onSelect={this.handleSelectSetting}
- selected={selected === NewCodePeriodSettingType.PREVIOUS_VERSION}
+ selected={selected === NewCodeDefinitionType.PreviousVersion}
/>
<NewCodeDefinitionDaysOption
days={days}
@@ -181,24 +191,24 @@ export default class BranchBaselineSettingModal extends React.PureComponent<Prop
isValid={isValid}
onChangeDays={this.handleSelectDays}
onSelect={this.handleSelectSetting}
- selected={selected === NewCodePeriodSettingType.NUMBER_OF_DAYS}
+ selected={selected === NewCodeDefinitionType.NumberOfDays}
/>
<BaselineSettingReferenceBranch
branchList={branchList.map(this.branchToOption)}
onChangeReferenceBranch={this.handleSelectReferenceBranch}
onSelect={this.handleSelectSetting}
referenceBranch={referenceBranch}
- selected={selected === NewCodePeriodSettingType.REFERENCE_BRANCH}
+ selected={selected === NewCodeDefinitionType.ReferenceBranch}
settingLevel="branch"
/>
- {currentSetting === NewCodePeriodSettingType.SPECIFIC_ANALYSIS && (
+ {currentSetting === NewCodeDefinitionType.SpecificAnalysis && (
<BaselineSettingAnalysis
onSelect={() => {}}
- selected={selected === NewCodePeriodSettingType.SPECIFIC_ANALYSIS}
+ selected={selected === NewCodeDefinitionType.SpecificAnalysis}
/>
)}
</div>
- {selected === NewCodePeriodSettingType.SPECIFIC_ANALYSIS && (
+ {selected === NewCodeDefinitionType.SpecificAnalysis && (
<BranchAnalysisList
analysis={analysis}
branch={branch.name}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchList.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchList.tsx
index 7d9943686e5..f8e5ab4c6ac 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchList.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchList.tsx
@@ -22,16 +22,18 @@ import { listBranchesNewCodePeriod, resetNewCodePeriod } from '../../../api/newC
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { isBranch, sortBranches } from '../../../helpers/branch-like';
import { translate } from '../../../helpers/l10n';
+import { DEFAULT_NEW_CODE_DEFINITION_TYPE } from '../../../helpers/new-code-definition';
import { Branch, BranchLike, BranchWithNewCodePeriod } from '../../../types/branch-like';
-import { Component, NewCodePeriod } from '../../../types/types';
-import { DEFAULT_GENERAL_SETTING_TYPE } from '../constants';
+import { NewCodeDefinition } from '../../../types/new-code-definition';
+import { Component } from '../../../types/types';
import BranchBaselineSettingModal from './BranchBaselineSettingModal';
import BranchListRow from './BranchListRow';
interface Props {
branchList: Branch[];
component: Component;
- inheritedSetting: NewCodePeriod;
+ inheritedSetting: NewCodeDefinition;
+ generalSetting: NewCodeDefinition;
}
interface State {
@@ -75,7 +77,7 @@ export default class BranchList extends React.PureComponent<Props, State> {
if (!newCodePeriod) {
return b;
}
- const { type = DEFAULT_GENERAL_SETTING_TYPE, value, effectiveValue } = newCodePeriod;
+ const { type = DEFAULT_NEW_CODE_DEFINITION_TYPE, value, effectiveValue } = newCodePeriod;
return {
...b,
newCodePeriod: { type, value, effectiveValue },
@@ -90,7 +92,7 @@ export default class BranchList extends React.PureComponent<Props, State> {
);
}
- updateBranchNewCodePeriod = (branch: string, newSetting: NewCodePeriod | undefined) => {
+ updateBranchNewCodePeriod = (branch: string, newSetting: NewCodeDefinition | undefined) => {
const { branches } = this.state;
const updated = branches.find((b) => b.name === branch);
@@ -104,7 +106,7 @@ export default class BranchList extends React.PureComponent<Props, State> {
this.setState({ editedBranch: branch });
};
- closeEditModal = (branch?: string, newSetting?: NewCodePeriod) => {
+ closeEditModal = (branch?: string, newSetting?: NewCodeDefinition) => {
if (branch) {
this.setState({
branches: this.updateBranchNewCodePeriod(branch, newSetting),
@@ -125,7 +127,7 @@ export default class BranchList extends React.PureComponent<Props, State> {
};
render() {
- const { branchList, inheritedSetting } = this.props;
+ const { branchList, inheritedSetting, generalSetting } = this.props;
const { branches, editedBranch, loading } = this.state;
if (branches.length < 1) {
@@ -167,6 +169,8 @@ export default class BranchList extends React.PureComponent<Props, State> {
branchList={branchList}
component={this.props.component.key}
onClose={this.closeEditModal}
+ inheritedSetting={inheritedSetting}
+ generalSetting={generalSetting}
/>
)}
</>
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchListRow.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchListRow.tsx
index 39197e19dd2..401c22eac16 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchListRow.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/BranchListRow.tsx
@@ -24,21 +24,21 @@ import BranchLikeIcon from '../../../components/icons/BranchLikeIcon';
import WarningIcon from '../../../components/icons/WarningIcon';
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { isNewCodeDefinitionCompliant } from '../../../helpers/periods';
+import { isNewCodeDefinitionCompliant } from '../../../helpers/new-code-definition';
import { BranchWithNewCodePeriod } from '../../../types/branch-like';
-import { NewCodePeriod, NewCodePeriodSettingType } from '../../../types/types';
+import { NewCodeDefinition, NewCodeDefinitionType } from '../../../types/new-code-definition';
export interface BranchListRowProps {
branch: BranchWithNewCodePeriod;
existingBranches: Array<string>;
- inheritedSetting: NewCodePeriod;
+ inheritedSetting: NewCodeDefinition;
onOpenEditModal: (branch: BranchWithNewCodePeriod) => void;
onResetToDefault: (branchName: string) => void;
}
-function renderNewCodePeriodSetting(newCodePeriod: NewCodePeriod) {
+function renderNewCodePeriodSetting(newCodePeriod: NewCodeDefinition) {
switch (newCodePeriod.type) {
- case NewCodePeriodSettingType.SPECIFIC_ANALYSIS:
+ case NewCodeDefinitionType.SpecificAnalysis:
return (
<>
{`${translate('baseline.specific_analysis')}: `}
@@ -49,11 +49,11 @@ function renderNewCodePeriodSetting(newCodePeriod: NewCodePeriod) {
)}
</>
);
- case NewCodePeriodSettingType.NUMBER_OF_DAYS:
+ case NewCodeDefinitionType.NumberOfDays:
return `${translate('new_code_definition.number_days')}: ${newCodePeriod.value}`;
- case NewCodePeriodSettingType.PREVIOUS_VERSION:
+ case NewCodeDefinitionType.PreviousVersion:
return translate('new_code_definition.previous_version');
- case NewCodePeriodSettingType.REFERENCE_BRANCH:
+ case NewCodeDefinitionType.ReferenceBranch:
return `${translate('baseline.reference_branch')}: ${newCodePeriod.value}`;
default:
return newCodePeriod.type;
@@ -62,11 +62,11 @@ function renderNewCodePeriodSetting(newCodePeriod: NewCodePeriod) {
function branchInheritsItselfAsReference(
branch: BranchWithNewCodePeriod,
- inheritedSetting: NewCodePeriod
+ inheritedSetting: NewCodeDefinition
) {
return (
!branch.newCodePeriod &&
- inheritedSetting.type === NewCodePeriodSettingType.REFERENCE_BRANCH &&
+ inheritedSetting.type === NewCodeDefinitionType.ReferenceBranch &&
branch.name === inheritedSetting.value
);
}
@@ -78,7 +78,7 @@ function referenceBranchDoesNotExist(
return (
branch.newCodePeriod &&
branch.newCodePeriod.value &&
- branch.newCodePeriod.type === NewCodePeriodSettingType.REFERENCE_BRANCH &&
+ branch.newCodePeriod.type === NewCodeDefinitionType.ReferenceBranch &&
!existingBranches.includes(branch.newCodePeriod.value)
);
}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineApp.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineApp.tsx
index 0b3f8674abd..5d185dd51ca 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineApp.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineApp.tsx
@@ -32,12 +32,16 @@ import AlertSuccessIcon from '../../../components/icons/AlertSuccessIcon';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { isBranch, sortBranches } from '../../../helpers/branch-like';
import { translate } from '../../../helpers/l10n';
+import {
+ DEFAULT_NEW_CODE_DEFINITION_TYPE,
+ getNumberOfDaysDefaultValue,
+} from '../../../helpers/new-code-definition';
import { AppState } from '../../../types/appstate';
import { Branch, BranchLike } from '../../../types/branch-like';
import { Feature } from '../../../types/features';
+import { NewCodeDefinition, NewCodeDefinitionType } from '../../../types/new-code-definition';
import { ParsedAnalysis } from '../../../types/project-activity';
-import { Component, NewCodePeriod, NewCodePeriodSettingType } from '../../../types/types';
-import { DEFAULT_GENERAL_SETTING_TYPE } from '../constants';
+import { Component } from '../../../types/types';
import '../styles.css';
import { getSettingValue } from '../utils';
import AppHeader from './AppHeader';
@@ -54,25 +58,23 @@ interface Props extends WithAvailableFeaturesProps {
interface State {
analysis?: string;
branchList: Branch[];
- currentSetting?: NewCodePeriodSettingType;
+ currentSetting?: NewCodeDefinitionType;
currentSettingValue?: string;
days: string;
- generalSetting?: NewCodePeriod;
+ generalSetting?: NewCodeDefinition;
loading: boolean;
overrideGeneralSetting?: boolean;
referenceBranch?: string;
saving: boolean;
- selected?: NewCodePeriodSettingType;
+ selected?: NewCodeDefinitionType;
success?: boolean;
}
-const DEFAULT_NUMBER_OF_DAYS = '30';
-
class ProjectBaselineApp extends React.PureComponent<Props, State> {
mounted = false;
state: State = {
branchList: [],
- days: DEFAULT_NUMBER_OF_DAYS,
+ days: getNumberOfDaysDefaultValue(),
loading: true,
saving: false,
};
@@ -97,16 +99,14 @@ class ProjectBaselineApp extends React.PureComponent<Props, State> {
}
getUpdatedState(params: {
- currentSetting?: NewCodePeriodSettingType;
+ currentSetting?: NewCodeDefinitionType;
currentSettingValue?: string;
- generalSetting: NewCodePeriod;
+ generalSetting: NewCodeDefinition;
}) {
const { currentSetting, currentSettingValue, generalSetting } = params;
const { referenceBranch } = this.state;
- const defaultDays =
- (generalSetting.type === NewCodePeriodSettingType.NUMBER_OF_DAYS && generalSetting.value) ||
- DEFAULT_NUMBER_OF_DAYS;
+ const defaultDays = getNumberOfDaysDefaultValue(generalSetting);
return {
loading: false,
@@ -116,13 +116,12 @@ class ProjectBaselineApp extends React.PureComponent<Props, State> {
selected: currentSetting || generalSetting.type,
overrideGeneralSetting: Boolean(currentSetting),
days:
- (currentSetting === NewCodePeriodSettingType.NUMBER_OF_DAYS && currentSettingValue) ||
+ (currentSetting === NewCodeDefinitionType.NumberOfDays && currentSettingValue) ||
defaultDays,
analysis:
- (currentSetting === NewCodePeriodSettingType.SPECIFIC_ANALYSIS && currentSettingValue) ||
- '',
+ (currentSetting === NewCodeDefinitionType.SpecificAnalysis && currentSettingValue) || '',
referenceBranch:
- (currentSetting === NewCodePeriodSettingType.REFERENCE_BRANCH && currentSettingValue) ||
+ (currentSetting === NewCodeDefinitionType.ReferenceBranch && currentSettingValue) ||
referenceBranch,
};
}
@@ -147,12 +146,12 @@ class ProjectBaselineApp extends React.PureComponent<Props, State> {
([generalSetting, setting]) => {
if (this.mounted) {
if (!generalSetting.type) {
- generalSetting = { type: DEFAULT_GENERAL_SETTING_TYPE };
+ generalSetting = { type: DEFAULT_NEW_CODE_DEFINITION_TYPE };
}
const currentSettingValue = setting.value;
const currentSetting = setting.inherited
? undefined
- : setting.type || DEFAULT_GENERAL_SETTING_TYPE;
+ : setting.type || DEFAULT_NEW_CODE_DEFINITION_TYPE;
this.setState(
this.getUpdatedState({
@@ -198,13 +197,13 @@ class ProjectBaselineApp extends React.PureComponent<Props, State> {
handleCancel = () =>
this.setState(
({
- generalSetting = { type: DEFAULT_GENERAL_SETTING_TYPE },
+ generalSetting = { type: DEFAULT_NEW_CODE_DEFINITION_TYPE },
currentSetting,
currentSettingValue,
}) => this.getUpdatedState({ generalSetting, currentSetting, currentSettingValue })
);
- handleSelectSetting = (selected?: NewCodePeriodSettingType) => this.setState({ selected });
+ handleSelectSetting = (selected?: NewCodeDefinitionType) => this.setState({ selected });
handleToggleSpecificSetting = (overrideGeneralSetting: boolean) =>
this.setState({ overrideGeneralSetting });
@@ -322,6 +321,7 @@ class ProjectBaselineApp extends React.PureComponent<Props, State> {
}
: generalSetting
}
+ generalSetting={generalSetting}
/>
</div>
)}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx
index f20cc30acfc..39f6c718421 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx
@@ -29,10 +29,10 @@ import NewCodeDefinitionWarning from '../../../components/new-code-definition/Ne
import { Alert } from '../../../components/ui/Alert';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { translate } from '../../../helpers/l10n';
-import { isNewCodeDefinitionCompliant } from '../../../helpers/periods';
+import { isNewCodeDefinitionCompliant } from '../../../helpers/new-code-definition';
import { Branch } from '../../../types/branch-like';
+import { NewCodeDefinition, NewCodeDefinitionType } from '../../../types/new-code-definition';
import { ParsedAnalysis } from '../../../types/project-activity';
-import { NewCodePeriod, NewCodePeriodSettingType } from '../../../types/types';
import { validateSetting } from '../utils';
import BaselineSettingAnalysis from './BaselineSettingAnalysis';
import BaselineSettingReferenceBranch from './BaselineSettingReferenceBranch';
@@ -45,20 +45,20 @@ export interface ProjectBaselineSelectorProps {
branchesEnabled?: boolean;
canAdmin: boolean | undefined;
component: string;
- currentSetting?: NewCodePeriodSettingType;
+ currentSetting?: NewCodeDefinitionType;
currentSettingValue?: string;
days: string;
- generalSetting: NewCodePeriod;
+ generalSetting: NewCodeDefinition;
onCancel: () => void;
onSelectAnalysis: (analysis: ParsedAnalysis) => void;
onSelectDays: (value: string) => void;
onSelectReferenceBranch: (value: string) => void;
- onSelectSetting: (value?: NewCodePeriodSettingType) => void;
+ onSelectSetting: (value?: NewCodeDefinitionType) => void;
onSubmit: (e: React.SyntheticEvent<HTMLFormElement>) => void;
onToggleSpecificSetting: (selection: boolean) => void;
referenceBranch?: string;
saving: boolean;
- selected?: NewCodePeriodSettingType;
+ selected?: NewCodeDefinitionType;
overrideGeneralSetting: boolean;
}
@@ -146,9 +146,7 @@ export default function ProjectBaselineSelector(props: ProjectBaselineSelectorPr
<NewCodeDefinitionPreviousVersionOption
disabled={!overrideGeneralSetting}
onSelect={props.onSelectSetting}
- selected={
- overrideGeneralSetting && selected === NewCodePeriodSettingType.PREVIOUS_VERSION
- }
+ selected={overrideGeneralSetting && selected === NewCodeDefinitionType.PreviousVersion}
/>
<NewCodeDefinitionDaysOption
days={days}
@@ -157,9 +155,7 @@ export default function ProjectBaselineSelector(props: ProjectBaselineSelectorPr
isValid={isValid}
onChangeDays={props.onSelectDays}
onSelect={props.onSelectSetting}
- selected={
- overrideGeneralSetting && selected === NewCodePeriodSettingType.NUMBER_OF_DAYS
- }
+ selected={overrideGeneralSetting && selected === NewCodeDefinitionType.NumberOfDays}
/>
{branchesEnabled && (
<BaselineSettingReferenceBranch
@@ -169,23 +165,23 @@ export default function ProjectBaselineSelector(props: ProjectBaselineSelectorPr
onSelect={props.onSelectSetting}
referenceBranch={referenceBranch || ''}
selected={
- overrideGeneralSetting && selected === NewCodePeriodSettingType.REFERENCE_BRANCH
+ overrideGeneralSetting && selected === NewCodeDefinitionType.ReferenceBranch
}
settingLevel="project"
/>
)}
- {!branchesEnabled && currentSetting === NewCodePeriodSettingType.SPECIFIC_ANALYSIS && (
+ {!branchesEnabled && currentSetting === NewCodeDefinitionType.SpecificAnalysis && (
<BaselineSettingAnalysis
onSelect={() => {}}
selected={
- overrideGeneralSetting && selected === NewCodePeriodSettingType.SPECIFIC_ANALYSIS
+ overrideGeneralSetting && selected === NewCodeDefinitionType.SpecificAnalysis
}
/>
)}
</div>
{!branchesEnabled &&
overrideGeneralSetting &&
- selected === NewCodePeriodSettingType.SPECIFIC_ANALYSIS && (
+ selected === NewCodeDefinitionType.SpecificAnalysis && (
<BranchAnalysisList
analysis={analysis || ''}
branch={branch.name}
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx
index b10faa7cdec..edcad7d025b 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx
@@ -25,7 +25,7 @@ import NewCodePeriodsServiceMock from '../../../../api/mocks/NewCodePeriodsServi
import { ProjectActivityServiceMock } from '../../../../api/mocks/ProjectActivityServiceMock';
import { mockBranch } from '../../../../helpers/mocks/branch-like';
import { mockComponent } from '../../../../helpers/mocks/component';
-import { mockNewCodePeriodBranch } from '../../../../helpers/mocks/new-code-period';
+import { mockNewCodePeriodBranch } from '../../../../helpers/mocks/new-code-definition';
import { mockAppState } from '../../../../helpers/testMocks';
import {
RenderContext,
@@ -33,7 +33,7 @@ import {
} from '../../../../helpers/testReactTestingUtils';
import { byRole, byText } from '../../../../helpers/testSelector';
import { Feature } from '../../../../types/features';
-import { NewCodePeriodSettingType } from '../../../../types/types';
+import { NewCodeDefinitionType } from '../../../../types/new-code-definition';
import routes from '../../routes';
jest.mock('../../../../api/newCodePeriod');
@@ -65,7 +65,7 @@ it('renders correctly without branch support feature', async () => {
it('prevents selection of global setting if it is not compliant and warns non-admin about it', async () => {
codePeriodsMock.setNewCodePeriod({
- type: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ type: NewCodeDefinitionType.NumberOfDays,
value: '99',
inherited: true,
});
@@ -81,7 +81,7 @@ it('prevents selection of global setting if it is not compliant and warns non-ad
it('prevents selection of global setting if it is not compliant and warns admin about it', async () => {
codePeriodsMock.setNewCodePeriod({
- type: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ type: NewCodeDefinitionType.NumberOfDays,
value: '99',
inherited: true,
});
@@ -177,7 +177,7 @@ it('can set reference branch specific setting', async () => {
it('cannot set specific analysis setting', async () => {
const { ui } = getPageObjects();
codePeriodsMock.setNewCodePeriod({
- type: NewCodePeriodSettingType.SPECIFIC_ANALYSIS,
+ type: NewCodeDefinitionType.SpecificAnalysis,
value: 'analysis_id',
});
renderProjectBaselineApp();
@@ -246,7 +246,7 @@ it('cannot set a specific analysis setting for branch', async () => {
codePeriodsMock.setListBranchesNewCode([
mockNewCodePeriodBranch({
branchKey: 'main',
- type: NewCodePeriodSettingType.SPECIFIC_ANALYSIS,
+ type: NewCodeDefinitionType.SpecificAnalysis,
value: 'analysis_id',
}),
]);
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts
index c9b2640b83c..1f50739f93c 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { NewCodePeriodSettingType } from '../../../../types/types';
+import { NewCodeDefinitionType } from '../../../../types/new-code-definition';
import { getSettingValue, validateSetting } from '../../utils';
describe('getSettingValue', () => {
@@ -28,25 +28,25 @@ describe('getSettingValue', () => {
};
it('should work for Days', () => {
- expect(getSettingValue({ ...state, type: NewCodePeriodSettingType.NUMBER_OF_DAYS })).toBe(
+ expect(getSettingValue({ ...state, type: NewCodeDefinitionType.NumberOfDays })).toBe(
state.days
);
});
it('should work for Analysis', () => {
- expect(getSettingValue({ ...state, type: NewCodePeriodSettingType.SPECIFIC_ANALYSIS })).toBe(
+ expect(getSettingValue({ ...state, type: NewCodeDefinitionType.SpecificAnalysis })).toBe(
state.analysis
);
});
it('should work for Previous version', () => {
expect(
- getSettingValue({ ...state, type: NewCodePeriodSettingType.PREVIOUS_VERSION })
+ getSettingValue({ ...state, type: NewCodeDefinitionType.PreviousVersion })
).toBeUndefined();
});
it('should work for Reference branch', () => {
- expect(getSettingValue({ ...state, type: NewCodePeriodSettingType.REFERENCE_BRANCH })).toBe(
+ expect(getSettingValue({ ...state, type: NewCodeDefinitionType.ReferenceBranch })).toBe(
state.referenceBranch
);
});
@@ -57,68 +57,68 @@ describe('validateSettings', () => {
expect(validateSetting({ days: '' })).toEqual({ isChanged: false, isValid: false });
expect(
validateSetting({
- currentSetting: NewCodePeriodSettingType.PREVIOUS_VERSION,
+ currentSetting: NewCodeDefinitionType.PreviousVersion,
days: '12',
- selected: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ selected: NewCodeDefinitionType.NumberOfDays,
})
).toEqual({ isChanged: true, isValid: true });
expect(
validateSetting({
- currentSetting: NewCodePeriodSettingType.PREVIOUS_VERSION,
+ currentSetting: NewCodeDefinitionType.PreviousVersion,
days: 'nope',
- selected: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ selected: NewCodeDefinitionType.NumberOfDays,
})
).toEqual({ isChanged: true, isValid: false });
expect(
validateSetting({
- currentSetting: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ currentSetting: NewCodeDefinitionType.NumberOfDays,
currentSettingValue: '15',
days: '15',
- selected: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ selected: NewCodeDefinitionType.NumberOfDays,
})
).toEqual({ isChanged: false, isValid: true });
expect(
validateSetting({
- currentSetting: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ currentSetting: NewCodeDefinitionType.NumberOfDays,
currentSettingValue: '15',
days: '13',
- selected: NewCodePeriodSettingType.NUMBER_OF_DAYS,
+ selected: NewCodeDefinitionType.NumberOfDays,
})
).toEqual({ isChanged: true, isValid: true });
expect(
validateSetting({
analysis: 'analysis1',
- currentSetting: NewCodePeriodSettingType.SPECIFIC_ANALYSIS,
+ currentSetting: NewCodeDefinitionType.SpecificAnalysis,
currentSettingValue: 'analysis1',
days: '',
- selected: NewCodePeriodSettingType.SPECIFIC_ANALYSIS,
+ selected: NewCodeDefinitionType.SpecificAnalysis,
})
).toEqual({ isChanged: false, isValid: false });
expect(
validateSetting({
analysis: 'analysis2',
- currentSetting: NewCodePeriodSettingType.SPECIFIC_ANALYSIS,
+ currentSetting: NewCodeDefinitionType.SpecificAnalysis,
currentSettingValue: 'analysis1',
days: '',
- selected: NewCodePeriodSettingType.SPECIFIC_ANALYSIS,
+ selected: NewCodeDefinitionType.SpecificAnalysis,
})
).toEqual({ isChanged: true, isValid: false });
expect(
validateSetting({
- currentSetting: NewCodePeriodSettingType.REFERENCE_BRANCH,
+ currentSetting: NewCodeDefinitionType.ReferenceBranch,
currentSettingValue: 'master',
days: '',
referenceBranch: 'master',
- selected: NewCodePeriodSettingType.REFERENCE_BRANCH,
+ selected: NewCodeDefinitionType.ReferenceBranch,
})
).toEqual({ isChanged: false, isValid: true });
expect(
validateSetting({
- currentSetting: NewCodePeriodSettingType.REFERENCE_BRANCH,
+ currentSetting: NewCodeDefinitionType.ReferenceBranch,
currentSettingValue: 'master',
days: '',
referenceBranch: '',
- selected: NewCodePeriodSettingType.REFERENCE_BRANCH,
+ selected: NewCodeDefinitionType.ReferenceBranch,
})
).toEqual({ isChanged: true, isValid: false });
});
@@ -134,7 +134,7 @@ describe('validateSettings', () => {
});
expect(
validateSetting({
- currentSetting: NewCodePeriodSettingType.PREVIOUS_VERSION,
+ currentSetting: NewCodeDefinitionType.PreviousVersion,
days: '',
overrideGeneralSetting: false,
})
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/utils.ts b/server/sonar-web/src/main/js/apps/projectBaseline/utils.ts
index f1dc41c7056..6a1076de85b 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/utils.ts
+++ b/server/sonar-web/src/main/js/apps/projectBaseline/utils.ts
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { isNewCodeDefinitionCompliant } from '../../helpers/periods';
-import { NewCodePeriodSettingType } from '../../types/types';
+import { isNewCodeDefinitionCompliant } from '../../helpers/new-code-definition';
+import { NewCodeDefinitionType } from '../../types/new-code-definition';
export function getSettingValue({
analysis,
@@ -29,14 +29,14 @@ export function getSettingValue({
analysis?: string;
days?: string;
referenceBranch?: string;
- type?: NewCodePeriodSettingType;
+ type?: NewCodeDefinitionType;
}) {
switch (type) {
- case NewCodePeriodSettingType.NUMBER_OF_DAYS:
+ case NewCodeDefinitionType.NumberOfDays:
return days;
- case NewCodePeriodSettingType.REFERENCE_BRANCH:
+ case NewCodeDefinitionType.ReferenceBranch:
return referenceBranch;
- case NewCodePeriodSettingType.SPECIFIC_ANALYSIS:
+ case NewCodeDefinitionType.SpecificAnalysis:
return analysis;
default:
return undefined;
@@ -45,12 +45,12 @@ export function getSettingValue({
export function validateSetting(state: {
analysis?: string;
- currentSetting?: NewCodePeriodSettingType;
+ currentSetting?: NewCodeDefinitionType;
currentSettingValue?: string;
days: string;
overrideGeneralSetting?: boolean;
referenceBranch?: string;
- selected?: NewCodePeriodSettingType;
+ selected?: NewCodeDefinitionType;
}) {
const {
analysis = '',
@@ -69,10 +69,9 @@ export function validateSetting(state: {
isChanged =
overrideGeneralSetting === false ||
selected !== currentSetting ||
- (selected === NewCodePeriodSettingType.NUMBER_OF_DAYS && days !== currentSettingValue) ||
- (selected === NewCodePeriodSettingType.SPECIFIC_ANALYSIS &&
- analysis !== currentSettingValue) ||
- (selected === NewCodePeriodSettingType.REFERENCE_BRANCH &&
+ (selected === NewCodeDefinitionType.NumberOfDays && days !== currentSettingValue) ||
+ (selected === NewCodeDefinitionType.SpecificAnalysis && analysis !== currentSettingValue) ||
+ (selected === NewCodeDefinitionType.ReferenceBranch &&
referenceBranch !== currentSettingValue);
}
@@ -83,8 +82,8 @@ export function validateSetting(state: {
type: selected,
value: days,
}) &&
- (selected !== NewCodePeriodSettingType.SPECIFIC_ANALYSIS || analysis.length > 0) &&
- (selected !== NewCodePeriodSettingType.REFERENCE_BRANCH || referenceBranch.length > 0));
+ (selected !== NewCodeDefinitionType.SpecificAnalysis || analysis.length > 0) &&
+ (selected !== NewCodeDefinitionType.ReferenceBranch || referenceBranch.length > 0));
return { isChanged, isValid };
}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/NewCodePeriod.tsx b/server/sonar-web/src/main/js/apps/settings/components/NewCodePeriod.tsx
index 96498f2fd8a..7dd692db76f 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/NewCodePeriod.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/NewCodePeriod.tsx
@@ -28,16 +28,19 @@ import NewCodeDefinitionPreviousVersionOption from '../../../components/new-code
import NewCodeDefinitionWarning from '../../../components/new-code-definition/NewCodeDefinitionWarning';
import DeferredSpinner from '../../../components/ui/DeferredSpinner';
import { translate } from '../../../helpers/l10n';
-import { isNewCodeDefinitionCompliant } from '../../../helpers/periods';
-import { NewCodePeriodSettingType } from '../../../types/types';
+import {
+ getNumberOfDaysDefaultValue,
+ isNewCodeDefinitionCompliant,
+} from '../../../helpers/new-code-definition';
+import { NewCodeDefinitionType } from '../../../types/new-code-definition';
interface State {
- currentSetting?: NewCodePeriodSettingType;
+ currentSetting?: NewCodeDefinitionType;
days: string;
loading: boolean;
currentSettingValue?: string;
saving: boolean;
- selected?: NewCodePeriodSettingType;
+ selected?: NewCodeDefinitionType;
success: boolean;
}
@@ -45,7 +48,7 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
mounted = false;
state: State = {
loading: true,
- days: '30',
+ days: getNumberOfDaysDefaultValue(),
saving: false,
success: false,
};
@@ -64,7 +67,7 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
.then(({ type, value }) => {
this.setState(({ days }) => ({
currentSetting: type,
- days: type === NewCodePeriodSettingType.NUMBER_OF_DAYS ? String(value) : days,
+ days: type === NewCodeDefinitionType.NumberOfDays ? String(value) : days,
loading: false,
currentSettingValue: value,
selected: type,
@@ -79,7 +82,7 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
this.setState({ days, success: false });
};
- onSelectSetting = (selected: NewCodePeriodSettingType) => {
+ onSelectSetting = (selected: NewCodeDefinitionType) => {
this.setState({ selected, success: false });
};
@@ -87,9 +90,7 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
this.setState(({ currentSetting, currentSettingValue, days }) => ({
selected: currentSetting,
days:
- currentSetting === NewCodePeriodSettingType.NUMBER_OF_DAYS
- ? String(currentSettingValue)
- : days,
+ currentSetting === NewCodeDefinitionType.NumberOfDays ? String(currentSettingValue) : days,
}));
};
@@ -99,25 +100,29 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
const { days, selected } = this.state;
const type = selected;
- const value = type === NewCodePeriodSettingType.NUMBER_OF_DAYS ? days : undefined;
+ const value = type === NewCodeDefinitionType.NumberOfDays ? days : undefined;
this.setState({ saving: true, success: false });
setNewCodePeriod({
- type: type as NewCodePeriodSettingType,
+ type: type as NewCodeDefinitionType,
value,
}).then(
() => {
- this.setState({
- saving: false,
- currentSetting: type,
- currentSettingValue: value || undefined,
- success: true,
- });
+ if (this.mounted) {
+ this.setState({
+ saving: false,
+ currentSetting: type,
+ currentSettingValue: value || undefined,
+ success: true,
+ });
+ }
},
() => {
- this.setState({
- saving: false,
- });
+ if (this.mounted) {
+ this.setState({
+ saving: false,
+ });
+ }
}
);
};
@@ -128,12 +133,11 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
const isChanged =
selected !== currentSetting ||
- (selected === NewCodePeriodSettingType.NUMBER_OF_DAYS &&
- String(days) !== currentSettingValue);
+ (selected === NewCodeDefinitionType.NumberOfDays && String(days) !== currentSettingValue);
const isValid =
- selected !== NewCodePeriodSettingType.NUMBER_OF_DAYS ||
- isNewCodeDefinitionCompliant({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: days });
+ selected !== NewCodeDefinitionType.NumberOfDays ||
+ isNewCodeDefinitionCompliant({ type: NewCodeDefinitionType.NumberOfDays, value: days });
return (
<>
@@ -187,7 +191,7 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
<NewCodeDefinitionPreviousVersionOption
isDefault
onSelect={this.onSelectSetting}
- selected={selected === NewCodePeriodSettingType.PREVIOUS_VERSION}
+ selected={selected === NewCodeDefinitionType.PreviousVersion}
/>
<NewCodeDefinitionDaysOption
className="spacer-top sw-mb-4"
@@ -196,7 +200,7 @@ export default class NewCodePeriod extends React.PureComponent<{}, State> {
isValid={isValid}
onChangeDays={this.onSelectDays}
onSelect={this.onSelectSetting}
- selected={selected === NewCodePeriodSettingType.NUMBER_OF_DAYS}
+ selected={selected === NewCodeDefinitionType.NumberOfDays}
/>
<NewCodeDefinitionWarning
newCodeDefinitionType={currentSetting}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx b/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx
index f8aba024f2e..e541c4e645f 100644
--- a/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx
+++ b/server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx
@@ -23,7 +23,7 @@ import * as React from 'react';
import NewCodePeriodsServiceMock from '../../../../api/mocks/NewCodePeriodsServiceMock';
import { renderComponent } from '../../../../helpers/testReactTestingUtils';
import { byRole, byText } from '../../../../helpers/testSelector';
-import { NewCodePeriodSettingType } from '../../../../types/types';
+import { NewCodeDefinitionType } from '../../../../types/new-code-definition';
import NewCodePeriod from '../NewCodePeriod';
let newCodeMock: NewCodePeriodsServiceMock;
@@ -93,7 +93,7 @@ it('renders and behaves as expected', async () => {
it('renders and behaves properly when the current value is not compliant', async () => {
const user = userEvent.setup();
- newCodeMock.setNewCodePeriod({ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '91' });
+ newCodeMock.setNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '91' });
renderNewCodePeriod();
expect(await ui.newCodeTitle.find()).toBeInTheDocument();
diff --git a/server/sonar-web/src/main/js/components/new-code-definition/GlobalNewCodeDefinitionDescription.tsx b/server/sonar-web/src/main/js/components/new-code-definition/GlobalNewCodeDefinitionDescription.tsx
index cf41e0236f6..b8d3ad3898c 100644
--- a/server/sonar-web/src/main/js/components/new-code-definition/GlobalNewCodeDefinitionDescription.tsx
+++ b/server/sonar-web/src/main/js/components/new-code-definition/GlobalNewCodeDefinitionDescription.tsx
@@ -20,12 +20,12 @@
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { translate, translateWithParameters } from '../../helpers/l10n';
-import { NewCodePeriod, NewCodePeriodSettingType } from '../../types/types';
+import { NewCodeDefinition, NewCodeDefinitionType } from '../../types/new-code-definition';
import Link from '../common/Link';
import { Alert } from '../ui/Alert';
interface Props {
- globalNcd: NewCodePeriod;
+ globalNcd: NewCodeDefinition;
isGlobalNcdCompliant: boolean;
canAdmin?: boolean;
}
@@ -38,7 +38,7 @@ export default function GlobalNewCodeDefinitionDescription({
let setting: string;
let description: string;
let useCase: string;
- if (globalNcd.type === NewCodePeriodSettingType.NUMBER_OF_DAYS) {
+ if (globalNcd.type === NewCodeDefinitionType.NumberOfDays) {
setting = `${translate('new_code_definition.number_days')} (${translateWithParameters(
'duration.days',
globalNcd.value ?? '?'
diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx
index 3d9511bbfc0..a3b52e9f642 100644
--- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx
+++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx
@@ -19,8 +19,11 @@
*/
import * as React from 'react';
import { translate, translateWithParameters } from '../../helpers/l10n';
-import { MAX_NUMBER_OF_DAYS, MIN_NUMBER_OF_DAYS } from '../../helpers/periods';
-import { NewCodePeriodSettingType } from '../../types/types';
+import {
+ NUMBER_OF_DAYS_MAX_VALUE,
+ NUMBER_OF_DAYS_MIN_VALUE,
+} from '../../helpers/new-code-definition';
+import { NewCodeDefinitionType } from '../../types/new-code-definition';
import RadioCard from '../controls/RadioCard';
import ValidationInput, { ValidationInputErrorPlacement } from '../controls/ValidationInput';
import MandatoryFieldsExplanation from '../ui/MandatoryFieldsExplanation';
@@ -32,7 +35,7 @@ export interface Props {
isChanged: boolean;
isValid: boolean;
onChangeDays: (value: string) => void;
- onSelect: (selection: NewCodePeriodSettingType) => void;
+ onSelect: (selection: NewCodeDefinitionType) => void;
selected: boolean;
}
@@ -44,7 +47,7 @@ export default function NewCodeDefinitionDaysOption(props: Props) {
noRadio
className={className}
disabled={disabled}
- onClick={() => onSelect(NewCodePeriodSettingType.NUMBER_OF_DAYS)}
+ onClick={() => onSelect(NewCodeDefinitionType.NumberOfDays)}
selected={selected}
title={translate('new_code_definition.number_days')}
>
@@ -64,8 +67,8 @@ export default function NewCodeDefinitionDaysOption(props: Props) {
errorPlacement={ValidationInputErrorPlacement.Bottom}
error={translateWithParameters(
'new_code_definition.number_days.invalid',
- MIN_NUMBER_OF_DAYS,
- MAX_NUMBER_OF_DAYS
+ NUMBER_OF_DAYS_MIN_VALUE,
+ NUMBER_OF_DAYS_MAX_VALUE
)}
label={translate('new_code_definition.number_days.specify_days')}
required
diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionPreviousVersionOption.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionPreviousVersionOption.tsx
index ec113fb06a1..60141f592e7 100644
--- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionPreviousVersionOption.tsx
+++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionPreviousVersionOption.tsx
@@ -19,13 +19,13 @@
*/
import * as React from 'react';
import { translate } from '../../helpers/l10n';
-import { NewCodePeriodSettingType } from '../../types/types';
+import { NewCodeDefinitionType } from '../../types/new-code-definition';
import RadioCard from '../controls/RadioCard';
interface Props {
disabled?: boolean;
isDefault?: boolean;
- onSelect: (selection: NewCodePeriodSettingType) => void;
+ onSelect: (selection: NewCodeDefinitionType) => void;
selected: boolean;
}
@@ -39,7 +39,7 @@ export default function NewCodeDefinitionPreviousVersionOption({
<RadioCard
noRadio
disabled={disabled}
- onClick={() => onSelect(NewCodePeriodSettingType.PREVIOUS_VERSION)}
+ onClick={() => onSelect(NewCodeDefinitionType.PreviousVersion)}
selected={selected}
title={
translate('new_code_definition.previous_version') +
diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx
index ef28eeff0fe..4a12a6a042a 100644
--- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx
+++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx
@@ -20,15 +20,17 @@
import { RadioButton } from 'design-system/lib';
import { noop } from 'lodash';
import * as React from 'react';
-import { useEffect } from 'react';
import { getNewCodePeriod } from '../../api/newCodePeriod';
import { translate } from '../../helpers/l10n';
-import { isNewCodeDefinitionCompliant } from '../../helpers/periods';
import {
- NewCodePeriod,
- NewCodePeriodSettingType,
- NewCodePeriodWithCompliance,
-} from '../../types/types';
+ getNumberOfDaysDefaultValue,
+ isNewCodeDefinitionCompliant,
+} from '../../helpers/new-code-definition';
+import {
+ NewCodeDefinition,
+ NewCodeDefinitionType,
+ NewCodeDefinitiondWithCompliance,
+} from '../../types/new-code-definition';
import RadioCard from '../controls/RadioCard';
import Tooltip from '../controls/Tooltip';
import { Alert } from '../ui/Alert';
@@ -38,28 +40,31 @@ import NewCodeDefinitionPreviousVersionOption from './NewCodeDefinitionPreviousV
interface Props {
canAdmin: boolean | undefined;
- onNcdChanged: (ncd: NewCodePeriodWithCompliance) => void;
+ onNcdChanged: (ncd: NewCodeDefinitiondWithCompliance) => void;
}
-const INITIAL_DAYS = '30';
-
export default function NewCodeDefinitionSelector(props: Props) {
const { canAdmin, onNcdChanged } = props;
- const [globalNcd, setGlobalNcd] = React.useState<NewCodePeriod | null>(null);
- const [selectedNcdType, setSelectedNcdType] = React.useState<NewCodePeriodSettingType | null>(
- null
- );
- const [days, setDays] = React.useState<string>(INITIAL_DAYS);
+ const [globalNcd, setGlobalNcd] = React.useState<NewCodeDefinition | null>(null);
+ const [selectedNcdType, setSelectedNcdType] = React.useState<NewCodeDefinitionType | null>(null);
+ const [days, setDays] = React.useState<string>('');
- const iGlobalNcdCompliant = React.useMemo(
+ const isGlobalNcdCompliant = React.useMemo(
() => Boolean(globalNcd && isNewCodeDefinitionCompliant(globalNcd)),
[globalNcd]
);
+ const initialNumberOfDays = React.useMemo(() => {
+ const numberOfDays = getNumberOfDaysDefaultValue(globalNcd);
+ setDays(numberOfDays);
+
+ return numberOfDays;
+ }, [globalNcd]);
+
const isChanged = React.useMemo(
- () => selectedNcdType === NewCodePeriodSettingType.NUMBER_OF_DAYS && days !== INITIAL_DAYS,
- [selectedNcdType, days]
+ () => selectedNcdType === NewCodeDefinitionType.NumberOfDays && days !== initialNumberOfDays,
+ [selectedNcdType, days, initialNumberOfDays]
);
const isCompliant = React.useMemo(
@@ -72,7 +77,7 @@ export default function NewCodeDefinitionSelector(props: Props) {
[selectedNcdType, days]
);
- useEffect(() => {
+ React.useEffect(() => {
function fetchGlobalNcd() {
getNewCodePeriod().then(setGlobalNcd, noop);
}
@@ -80,11 +85,11 @@ export default function NewCodeDefinitionSelector(props: Props) {
fetchGlobalNcd();
}, []);
- useEffect(() => {
+ React.useEffect(() => {
if (selectedNcdType) {
const type =
- selectedNcdType === NewCodePeriodSettingType.INHERITED ? undefined : selectedNcdType;
- const value = selectedNcdType === NewCodePeriodSettingType.NUMBER_OF_DAYS ? days : undefined;
+ selectedNcdType === NewCodeDefinitionType.Inherited ? undefined : selectedNcdType;
+ const value = selectedNcdType === NewCodeDefinitionType.NumberOfDays ? days : undefined;
onNcdChanged({ isCompliant, type, value });
}
}, [selectedNcdType, days, isCompliant, onNcdChanged]);
@@ -97,15 +102,15 @@ export default function NewCodeDefinitionSelector(props: Props) {
<div className="big-spacer-top spacer-bottom" role="radiogroup">
<RadioButton
aria-label={translate('new_code_definition.global_setting')}
- checked={selectedNcdType === NewCodePeriodSettingType.INHERITED}
+ checked={selectedNcdType === NewCodeDefinitionType.Inherited}
className="big-spacer-bottom"
- disabled={!iGlobalNcdCompliant}
- onCheck={() => setSelectedNcdType(NewCodePeriodSettingType.INHERITED)}
+ disabled={!isGlobalNcdCompliant}
+ onCheck={() => setSelectedNcdType(NewCodeDefinitionType.Inherited)}
value="general"
>
<Tooltip
overlay={
- iGlobalNcdCompliant
+ isGlobalNcdCompliant
? null
: translate('new_code_definition.compliance.warning.title.global')
}
@@ -118,7 +123,7 @@ export default function NewCodeDefinitionSelector(props: Props) {
{globalNcd && (
<GlobalNewCodeDefinitionDescription
globalNcd={globalNcd}
- isGlobalNcdCompliant={iGlobalNcdCompliant}
+ isGlobalNcdCompliant={isGlobalNcdCompliant}
canAdmin={canAdmin}
/>
)}
@@ -126,11 +131,9 @@ export default function NewCodeDefinitionSelector(props: Props) {
<RadioButton
aria-label={translate('new_code_definition.specific_setting')}
- checked={Boolean(
- selectedNcdType && selectedNcdType !== NewCodePeriodSettingType.INHERITED
- )}
+ checked={Boolean(selectedNcdType && selectedNcdType !== NewCodeDefinitionType.Inherited)}
className="huge-spacer-top"
- onCheck={() => setSelectedNcdType(NewCodePeriodSettingType.PREVIOUS_VERSION)}
+ onCheck={() => setSelectedNcdType(NewCodeDefinitionType.PreviousVersion)}
value="specific"
>
{translate('new_code_definition.specific_setting')}
@@ -141,31 +144,31 @@ export default function NewCodeDefinitionSelector(props: Props) {
<div className="display-flex-row big-spacer-bottom" role="radiogroup">
<NewCodeDefinitionPreviousVersionOption
disabled={Boolean(
- !selectedNcdType || selectedNcdType === NewCodePeriodSettingType.INHERITED
+ !selectedNcdType || selectedNcdType === NewCodeDefinitionType.Inherited
)}
onSelect={setSelectedNcdType}
- selected={selectedNcdType === NewCodePeriodSettingType.PREVIOUS_VERSION}
+ selected={selectedNcdType === NewCodeDefinitionType.PreviousVersion}
/>
<NewCodeDefinitionDaysOption
days={days}
disabled={Boolean(
- !selectedNcdType || selectedNcdType === NewCodePeriodSettingType.INHERITED
+ !selectedNcdType || selectedNcdType === NewCodeDefinitionType.Inherited
)}
isChanged={isChanged}
isValid={isCompliant}
onChangeDays={setDays}
onSelect={setSelectedNcdType}
- selected={selectedNcdType === NewCodePeriodSettingType.NUMBER_OF_DAYS}
+ selected={selectedNcdType === NewCodeDefinitionType.NumberOfDays}
/>
<RadioCard
noRadio
disabled={Boolean(
- !selectedNcdType || selectedNcdType === NewCodePeriodSettingType.INHERITED
+ !selectedNcdType || selectedNcdType === NewCodeDefinitionType.Inherited
)}
- onClick={() => setSelectedNcdType(NewCodePeriodSettingType.REFERENCE_BRANCH)}
- selected={selectedNcdType === NewCodePeriodSettingType.REFERENCE_BRANCH}
+ onClick={() => setSelectedNcdType(NewCodeDefinitionType.ReferenceBranch)}
+ selected={selectedNcdType === NewCodeDefinitionType.ReferenceBranch}
title={translate('new_code_definition.reference_branch')}
>
<div>
@@ -173,7 +176,7 @@ export default function NewCodeDefinitionSelector(props: Props) {
{translate('new_code_definition.reference_branch.description')}
</p>
<p className="sw-mb-4">{translate('new_code_definition.reference_branch.usecase')}</p>
- {selectedNcdType === NewCodePeriodSettingType.REFERENCE_BRANCH && (
+ {selectedNcdType === NewCodeDefinitionType.ReferenceBranch && (
<Alert variant="info">
{translate('new_code_definition.reference_branch.notice')}
</Alert>
diff --git a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionWarning.tsx b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionWarning.tsx
index dfbc9c9f503..60e23dcecae 100644
--- a/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionWarning.tsx
+++ b/server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionWarning.tsx
@@ -20,13 +20,13 @@
import * as React from 'react';
import { translate } from '../../helpers/l10n';
-import { isNewCodeDefinitionCompliant } from '../../helpers/periods';
-import { NewCodePeriodSettingType } from '../../types/types';
+import { isNewCodeDefinitionCompliant } from '../../helpers/new-code-definition';
+import { NewCodeDefinitionType } from '../../types/new-code-definition';
import DocLink from '../common/DocLink';
import { Alert } from '../ui/Alert';
export interface NewCodeDefinitionWarningProps {
- newCodeDefinitionType: NewCodePeriodSettingType | undefined;
+ newCodeDefinitionType: NewCodeDefinitionType | undefined;
newCodeDefinitionValue: string | undefined;
isBranchSupportEnabled: boolean | undefined;
level: 'branch' | 'project' | 'global';
@@ -45,7 +45,7 @@ export default function NewCodeDefinitionWarning({
return null;
}
- if (newCodeDefinitionType === NewCodePeriodSettingType.SPECIFIC_ANALYSIS) {
+ if (newCodeDefinitionType === NewCodeDefinitionType.SpecificAnalysis) {
return (
<Alert variant="warning" className="sw-mb-4 sw-max-w-[800px]">
<p className="sw-mb-2 sw-font-bold">
@@ -64,7 +64,7 @@ export default function NewCodeDefinitionWarning({
);
}
- if (newCodeDefinitionType === NewCodePeriodSettingType.NUMBER_OF_DAYS) {
+ if (newCodeDefinitionType === NewCodeDefinitionType.NumberOfDays) {
return (
<Alert variant="warning" className="sw-mb-4 sw-max-w-[800px]">
<p className="sw-mb-2 sw-font-bold">
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/new-code-definition-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/new-code-definition-test.ts
new file mode 100644
index 00000000000..7368b3c15a8
--- /dev/null
+++ b/server/sonar-web/src/main/js/helpers/__tests__/new-code-definition-test.ts
@@ -0,0 +1,84 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 { NewCodeDefinition, NewCodeDefinitionType } from '../../types/new-code-definition';
+import { mockNewCodePeriod } from '../mocks/new-code-definition';
+import {
+ NUMBER_OF_DAYS_DEFAULT_VALUE,
+ getNumberOfDaysDefaultValue,
+ isNewCodeDefinitionCompliant,
+} from '../new-code-definition';
+
+describe('isNewCodeDefinitionCompliant', () => {
+ it.each([
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '0' }), false],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '15' }), true],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '15.' }), false],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '15.0' }), false],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '15.3' }), false],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '91' }), false],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.PreviousVersion }), true],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.ReferenceBranch }), true],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.SpecificAnalysis }), false],
+ ])(
+ 'should test for new code definition compliance properly %s',
+ (newCodePeriod: NewCodeDefinition, result: boolean) => {
+ expect(isNewCodeDefinitionCompliant(newCodePeriod)).toEqual(result);
+ }
+ );
+});
+
+describe('getNumberOfDaysDefaultValue', () => {
+ it.each([
+ [null, null, NUMBER_OF_DAYS_DEFAULT_VALUE.toString()],
+ [
+ mockNewCodePeriod({ type: NewCodeDefinitionType.PreviousVersion }),
+ null,
+ NUMBER_OF_DAYS_DEFAULT_VALUE.toString(),
+ ],
+ [
+ null,
+ mockNewCodePeriod({ type: NewCodeDefinitionType.PreviousVersion }),
+ NUMBER_OF_DAYS_DEFAULT_VALUE.toString(),
+ ],
+ [
+ mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '91' }),
+ null,
+ NUMBER_OF_DAYS_DEFAULT_VALUE.toString(),
+ ],
+ [
+ null,
+ mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '91' }),
+ NUMBER_OF_DAYS_DEFAULT_VALUE.toString(),
+ ],
+ [mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '90' }), null, '90'],
+ [null, mockNewCodePeriod({ type: NewCodeDefinitionType.NumberOfDays, value: '90' }), '90'],
+ ])(
+ 'should return the defaut number of days vale properly %s',
+ (
+ globalNewCodeDefinition: NewCodeDefinition | null,
+ inheritedNewCodeDefinition: NewCodeDefinition | null,
+ result: string
+ ) => {
+ expect(
+ getNumberOfDaysDefaultValue(globalNewCodeDefinition, inheritedNewCodeDefinition)
+ ).toEqual(result);
+ }
+ );
+});
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/periods-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/new-code-period-test.ts
index aca69741c93..52011866a7d 100644
--- a/server/sonar-web/src/main/js/helpers/__tests__/periods-test.ts
+++ b/server/sonar-web/src/main/js/helpers/__tests__/new-code-period-test.ts
@@ -17,8 +17,8 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { NewCodePeriod, NewCodePeriodSettingType } from '../../types/types';
-import { getPeriodLabel, isNewCodeDefinitionCompliant } from '../periods';
+import { NewCodeDefinitionType } from '../../types/new-code-definition';
+import { getNewCodePeriodLabel } from '../new-code-period';
import { mockPeriod } from '../testMocks';
const formatter = jest.fn((v) => v);
@@ -29,19 +29,24 @@ beforeEach(() => {
describe('getPeriodLabel', () => {
it('should handle missing value', () => {
- expect(getPeriodLabel(undefined, formatter)).toBeUndefined();
+ expect(getNewCodePeriodLabel(undefined, formatter)).toBeUndefined();
});
it('should handle date', () => {
- expect(getPeriodLabel(mockPeriod({ mode: 'date' }), formatter)).toBe('overview.period.date.');
+ expect(getNewCodePeriodLabel(mockPeriod({ mode: 'date' }), formatter)).toBe(
+ 'overview.period.date.'
+ );
expect(
- getPeriodLabel(mockPeriod({ mode: 'date', parameter: '2019-02-21T01:11:21+0100' }), formatter)
+ getNewCodePeriodLabel(
+ mockPeriod({ mode: 'date', parameter: '2019-02-21T01:11:21+0100' }),
+ formatter
+ )
).toBe('overview.period.date.2019-02-21T01:11:21+0100');
expect(formatter).toHaveBeenCalledTimes(1);
});
it('should handle days', () => {
- expect(getPeriodLabel(mockPeriod({ mode: 'days', modeParam: '12' }), formatter)).toBe(
+ expect(getNewCodePeriodLabel(mockPeriod({ mode: 'days', modeParam: '12' }), formatter)).toBe(
'overview.period.days.12'
);
expect(formatter).not.toHaveBeenCalled();
@@ -49,36 +54,42 @@ describe('getPeriodLabel', () => {
it('should handle previous analysis', () => {
expect(
- getPeriodLabel(mockPeriod({ mode: 'previous_analysis', parameter: 'param' }), formatter)
+ getNewCodePeriodLabel(
+ mockPeriod({ mode: 'previous_analysis', parameter: 'param' }),
+ formatter
+ )
).toBe('overview.period.previous_analysis.param');
expect(formatter).not.toHaveBeenCalled();
});
it('should handle previous version', () => {
- expect(getPeriodLabel(mockPeriod({ mode: 'previous_version' }), formatter)).toBe(
+ expect(getNewCodePeriodLabel(mockPeriod({ mode: 'previous_version' }), formatter)).toBe(
'overview.period.previous_version_only_date'
);
expect(
- getPeriodLabel(mockPeriod({ mode: 'previous_version', parameter: '7.9' }), formatter)
+ getNewCodePeriodLabel(mockPeriod({ mode: 'previous_version', parameter: '7.9' }), formatter)
).toBe('overview.period.previous_version.7.9');
expect(formatter).not.toHaveBeenCalled();
});
it('should handle version', () => {
- expect(getPeriodLabel(mockPeriod({ mode: 'version', modeParam: '7.2' }), formatter)).toBe(
- 'overview.period.version.7.2'
- );
expect(
- getPeriodLabel(mockPeriod({ mode: 'previous_version', parameter: '7.9' }), formatter)
+ getNewCodePeriodLabel(mockPeriod({ mode: 'version', modeParam: '7.2' }), formatter)
+ ).toBe('overview.period.version.7.2');
+ expect(
+ getNewCodePeriodLabel(mockPeriod({ mode: 'previous_version', parameter: '7.9' }), formatter)
).toBe('overview.period.previous_version.7.9');
expect(formatter).not.toHaveBeenCalled();
});
it('should handle manual baseline', () => {
expect(
- getPeriodLabel(mockPeriod({ mode: 'manual_baseline', modeParam: 'A658678DE' }), formatter)
+ getNewCodePeriodLabel(
+ mockPeriod({ mode: 'manual_baseline', modeParam: 'A658678DE' }),
+ formatter
+ )
).toBe('overview.period.manual_baseline.A658678DE');
- expect(getPeriodLabel(mockPeriod({ mode: 'manual_baseline' }), formatter)).toBe(
+ expect(getNewCodePeriodLabel(mockPeriod({ mode: 'manual_baseline' }), formatter)).toBe(
'overview.period.manual_baseline.2019-04-23T02:12:32+0100'
);
expect(formatter).toHaveBeenCalledTimes(1);
@@ -86,46 +97,27 @@ describe('getPeriodLabel', () => {
it('should handle SPECIFIC_ANALYSIS', () => {
expect(
- getPeriodLabel(
- mockPeriod({ mode: NewCodePeriodSettingType.SPECIFIC_ANALYSIS, parameter: '7.1' }),
+ getNewCodePeriodLabel(
+ mockPeriod({ mode: NewCodeDefinitionType.SpecificAnalysis, parameter: '7.1' }),
formatter
)
).toBe('overview.period.specific_analysis.2019-04-23T02:12:32+0100');
expect(
- getPeriodLabel(mockPeriod({ mode: NewCodePeriodSettingType.SPECIFIC_ANALYSIS }), formatter)
+ getNewCodePeriodLabel(mockPeriod({ mode: NewCodeDefinitionType.SpecificAnalysis }), formatter)
).toBe('overview.period.specific_analysis.2019-04-23T02:12:32+0100');
expect(formatter).toHaveBeenCalledTimes(2);
});
it('should handle PREVIOUS_VERSION', () => {
expect(
- getPeriodLabel(
- mockPeriod({ mode: NewCodePeriodSettingType.PREVIOUS_VERSION, modeParam: 'A658678DE' }),
+ getNewCodePeriodLabel(
+ mockPeriod({ mode: NewCodeDefinitionType.PreviousVersion, modeParam: 'A658678DE' }),
formatter
)
).toBe('overview.period.previous_version.A658678DE');
expect(
- getPeriodLabel(mockPeriod({ mode: NewCodePeriodSettingType.PREVIOUS_VERSION }), formatter)
+ getNewCodePeriodLabel(mockPeriod({ mode: NewCodeDefinitionType.PreviousVersion }), formatter)
).toBe('overview.period.previous_version.2019-04-23T02:12:32+0100');
expect(formatter).toHaveBeenCalledTimes(1);
});
});
-
-describe('isNewCodeDefinitionCompliant', () => {
- it.each([
- [{ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '0' }, false],
- [{ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '15' }, true],
- [{ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '15.' }, false],
- [{ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '15.0' }, false],
- [{ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '15.3' }, false],
- [{ type: NewCodePeriodSettingType.NUMBER_OF_DAYS, value: '91' }, false],
- [{ type: NewCodePeriodSettingType.PREVIOUS_VERSION }, true],
- [{ type: NewCodePeriodSettingType.REFERENCE_BRANCH }, true],
- [{ type: NewCodePeriodSettingType.SPECIFIC_ANALYSIS }, false],
- ])(
- 'should test for new code definition compliance properly %s',
- (newCodePeriod: NewCodePeriod, result: boolean) => {
- expect(isNewCodeDefinitionCompliant(newCodePeriod)).toEqual(result);
- }
- );
-});
diff --git a/server/sonar-web/src/main/js/helpers/mocks/new-code-period.ts b/server/sonar-web/src/main/js/helpers/mocks/new-code-definition.ts
index a4372621720..72ecf4f8c61 100644
--- a/server/sonar-web/src/main/js/helpers/mocks/new-code-period.ts
+++ b/server/sonar-web/src/main/js/helpers/mocks/new-code-definition.ts
@@ -18,16 +18,22 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { NewCodePeriod, NewCodePeriodBranch, NewCodePeriodSettingType } from '../../types/types';
+import {
+ NewCodeDefinition,
+ NewCodeDefinitionBranch,
+ NewCodeDefinitionType,
+} from '../../types/new-code-definition';
-export function mockNewCodePeriod(overrides: Partial<NewCodePeriod> = {}) {
+export function mockNewCodePeriod(overrides: Partial<NewCodeDefinition> = {}): NewCodeDefinition {
return {
- type: NewCodePeriodSettingType.PREVIOUS_VERSION,
+ type: NewCodeDefinitionType.PreviousVersion,
...overrides,
};
}
-export function mockNewCodePeriodBranch(overrides: Partial<NewCodePeriodBranch> = {}) {
+export function mockNewCodePeriodBranch(
+ overrides: Partial<NewCodeDefinitionBranch> = {}
+): NewCodeDefinitionBranch {
return {
projectKey: 'pkey',
branchKey: 'bKey',
diff --git a/server/sonar-web/src/main/js/helpers/new-code-definition.ts b/server/sonar-web/src/main/js/helpers/new-code-definition.ts
new file mode 100644
index 00000000000..d02b8742c62
--- /dev/null
+++ b/server/sonar-web/src/main/js/helpers/new-code-definition.ts
@@ -0,0 +1,70 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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 { NewCodeDefinition, NewCodeDefinitionType } from '../types/new-code-definition';
+
+export const DEFAULT_NEW_CODE_DEFINITION_TYPE: NewCodeDefinitionType =
+ NewCodeDefinitionType.PreviousVersion;
+export const NUMBER_OF_DAYS_MIN_VALUE = 1;
+export const NUMBER_OF_DAYS_MAX_VALUE = 90;
+export const NUMBER_OF_DAYS_DEFAULT_VALUE = 30;
+
+export function isNewCodeDefinitionCompliant(newCodePeriod: NewCodeDefinition) {
+ switch (newCodePeriod.type) {
+ case NewCodeDefinitionType.NumberOfDays:
+ if (!newCodePeriod.value) {
+ return false;
+ }
+ return (
+ !/\D/.test(newCodePeriod.value) &&
+ Number.isInteger(+newCodePeriod.value) &&
+ NUMBER_OF_DAYS_MIN_VALUE <= +newCodePeriod.value &&
+ +newCodePeriod.value <= NUMBER_OF_DAYS_MAX_VALUE
+ );
+ case NewCodeDefinitionType.SpecificAnalysis:
+ return false;
+ default:
+ return true;
+ }
+}
+
+export function getNumberOfDaysDefaultValue(
+ globalNewCodeDefinition?: NewCodeDefinition | null,
+ inheritedNewCodeDefinition?: NewCodeDefinition | null
+) {
+ if (
+ inheritedNewCodeDefinition &&
+ isNewCodeDefinitionCompliant(inheritedNewCodeDefinition) &&
+ inheritedNewCodeDefinition.type === NewCodeDefinitionType.NumberOfDays &&
+ inheritedNewCodeDefinition.value
+ ) {
+ return inheritedNewCodeDefinition.value;
+ }
+
+ if (
+ globalNewCodeDefinition &&
+ isNewCodeDefinitionCompliant(globalNewCodeDefinition) &&
+ globalNewCodeDefinition.type === NewCodeDefinitionType.NumberOfDays &&
+ globalNewCodeDefinition.value
+ ) {
+ return globalNewCodeDefinition.value;
+ }
+
+ return NUMBER_OF_DAYS_DEFAULT_VALUE.toString();
+}
diff --git a/server/sonar-web/src/main/js/helpers/periods.ts b/server/sonar-web/src/main/js/helpers/new-code-period.ts
index 7e80ce8a8d2..7d92c9521ef 100644
--- a/server/sonar-web/src/main/js/helpers/periods.ts
+++ b/server/sonar-web/src/main/js/helpers/new-code-period.ts
@@ -17,12 +17,17 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { parseDate } from '../helpers/dates';
-import { translate, translateWithParameters } from '../helpers/l10n';
import { ApplicationPeriod } from '../types/application';
-import { NewCodePeriod, NewCodePeriodSettingType, Period } from '../types/types';
+import { NewCodeDefinitionType } from '../types/new-code-definition';
+import { Period } from '../types/types';
+import { parseDate } from './dates';
+import { translate, translateWithParameters } from './l10n';
-export function getPeriodLabel(
+export function getNewCodePeriodDate(period?: { date?: string }): Date | undefined {
+ return period?.date ? parseDate(period.date) : undefined;
+}
+
+export function getNewCodePeriodLabel(
period: Period | undefined,
dateFormatter: (date: string) => string
) {
@@ -33,10 +38,10 @@ export function getPeriodLabel(
let parameter = period.modeParam || period.parameter || '';
switch (period.mode) {
- case NewCodePeriodSettingType.SPECIFIC_ANALYSIS:
+ case NewCodeDefinitionType.SpecificAnalysis:
parameter = dateFormatter(period.date);
break;
- case NewCodePeriodSettingType.PREVIOUS_VERSION:
+ case NewCodeDefinitionType.PreviousVersion:
parameter = parameter || dateFormatter(period.date);
break;
/*
@@ -59,34 +64,8 @@ export function getPeriodLabel(
return translateWithParameters(`overview.period.${period.mode.toLowerCase()}`, parameter);
}
-export function getPeriodDate(period?: { date?: string }): Date | undefined {
- return period && period.date ? parseDate(period.date) : undefined;
-}
-
-export function isApplicationPeriod(
+export function isApplicationNewCodePeriod(
period: Period | ApplicationPeriod
): period is ApplicationPeriod {
return (period as ApplicationPeriod).project !== undefined;
}
-
-export const MIN_NUMBER_OF_DAYS = 1;
-export const MAX_NUMBER_OF_DAYS = 90;
-
-export function isNewCodeDefinitionCompliant(newCodePeriod: NewCodePeriod) {
- switch (newCodePeriod.type) {
- case NewCodePeriodSettingType.NUMBER_OF_DAYS:
- if (!newCodePeriod.value) {
- return false;
- }
- return (
- !/\D/.test(newCodePeriod.value) &&
- Number.isInteger(+newCodePeriod.value) &&
- MIN_NUMBER_OF_DAYS <= +newCodePeriod.value &&
- +newCodePeriod.value <= MAX_NUMBER_OF_DAYS
- );
- case NewCodePeriodSettingType.SPECIFIC_ANALYSIS:
- return false;
- default:
- return true;
- }
-}
diff --git a/server/sonar-web/src/main/js/types/branch-like.ts b/server/sonar-web/src/main/js/types/branch-like.ts
index f25c8a11693..6f1056dcf6b 100644
--- a/server/sonar-web/src/main/js/types/branch-like.ts
+++ b/server/sonar-web/src/main/js/types/branch-like.ts
@@ -17,8 +17,9 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { NewCodeDefinition } from './new-code-definition';
import { QualityGateStatusCondition } from './quality-gates';
-import { NewCodePeriod, Status } from './types';
+import { Status } from './types';
export interface Branch {
analysisDate?: string;
@@ -61,7 +62,7 @@ export interface BranchLikeTree {
export type BranchParameters = { branch?: string } | { pullRequest?: string };
export interface BranchWithNewCodePeriod extends Branch {
- newCodePeriod?: NewCodePeriod;
+ newCodePeriod?: NewCodeDefinition;
}
export interface BranchStatusData {
diff --git a/server/sonar-web/src/main/js/apps/projectBaseline/constants.ts b/server/sonar-web/src/main/js/types/new-code-definition.ts
index 00c2c82e24b..9bda3b52432 100644
--- a/server/sonar-web/src/main/js/apps/projectBaseline/constants.ts
+++ b/server/sonar-web/src/main/js/types/new-code-definition.ts
@@ -18,7 +18,28 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-import { NewCodePeriodSettingType } from '../../types/types';
+export enum NewCodeDefinitionType {
+ PreviousVersion = 'PREVIOUS_VERSION',
+ NumberOfDays = 'NUMBER_OF_DAYS',
+ SpecificAnalysis = 'SPECIFIC_ANALYSIS',
+ ReferenceBranch = 'REFERENCE_BRANCH',
+ Inherited = 'INHERITED',
+}
-export const DEFAULT_GENERAL_SETTING_TYPE: NewCodePeriodSettingType =
- NewCodePeriodSettingType.PREVIOUS_VERSION;
+export interface NewCodeDefinition {
+ type: NewCodeDefinitionType;
+ value?: string;
+ effectiveValue?: string;
+ inherited?: boolean;
+}
+
+export interface NewCodeDefinitiondWithCompliance {
+ type?: NewCodeDefinitionType;
+ value?: string;
+ isCompliant: boolean;
+}
+
+export interface NewCodeDefinitionBranch extends NewCodeDefinition {
+ projectKey: string;
+ branchKey: string;
+}
diff --git a/server/sonar-web/src/main/js/types/types.ts b/server/sonar-web/src/main/js/types/types.ts
index f31661e0c7f..a83e6bb36c8 100644
--- a/server/sonar-web/src/main/js/types/types.ts
+++ b/server/sonar-web/src/main/js/types/types.ts
@@ -20,6 +20,7 @@
import { RuleDescriptionSection } from '../apps/coding-rules/rule';
import { ComponentQualifier, Visibility } from './component';
import { MessageFormatting } from './issues';
+import { NewCodeDefinitionType } from './new-code-definition';
import { UserActive, UserBase } from './users';
export type Dict<T> = { [key: string]: T };
@@ -397,32 +398,6 @@ export interface MyProject {
qualityGate?: string;
}
-export interface NewCodePeriod {
- type: NewCodePeriodSettingType;
- value?: string;
- effectiveValue?: string;
- inherited?: boolean;
-}
-
-export interface NewCodePeriodWithCompliance {
- type?: NewCodePeriodSettingType;
- value?: string;
- isCompliant: boolean;
-}
-
-export interface NewCodePeriodBranch extends NewCodePeriod {
- projectKey: string;
- branchKey: string;
-}
-
-export enum NewCodePeriodSettingType {
- PREVIOUS_VERSION = 'PREVIOUS_VERSION',
- NUMBER_OF_DAYS = 'NUMBER_OF_DAYS',
- SPECIFIC_ANALYSIS = 'SPECIFIC_ANALYSIS',
- REFERENCE_BRANCH = 'REFERENCE_BRANCH',
- INHERITED = 'INHERITED',
-}
-
export interface Paging {
pageIndex: number;
pageSize: number;
@@ -432,7 +407,7 @@ export interface Paging {
export interface Period {
date: string;
index?: number;
- mode: PeriodMode | NewCodePeriodSettingType;
+ mode: PeriodMode | NewCodeDefinitionType;
modeParam?: string;
parameter?: string;
}