]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-19687 Non-compliant global new code definition value should not be proposed...
authorPhilippe Perrin <philippe.perrin@sonarsource.com>
Thu, 8 Jun 2023 08:22:27 +0000 (10:22 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 26 Jun 2023 20:03:54 +0000 (20:03 +0000)
40 files changed:
server/sonar-web/src/main/js/api/mocks/NewCodePeriodsServiceMock.ts
server/sonar-web/src/main/js/api/newCodePeriod.ts
server/sonar-web/src/main/js/apps/component-measures/components/LeakPeriodLegend.tsx
server/sonar-web/src/main/js/apps/create/project/CreateProjectPage.tsx
server/sonar-web/src/main/js/apps/create/project/__tests__/Manual-it.tsx
server/sonar-web/src/main/js/apps/create/project/types.ts
server/sonar-web/src/main/js/apps/overview/branches/LeakPeriodInfo.tsx
server/sonar-web/src/main/js/apps/overview/branches/MeasuresPanelNoNewCode.tsx
server/sonar-web/src/main/js/apps/overview/branches/ProjectLeakPeriodInfo.tsx
server/sonar-web/src/main/js/apps/overview/branches/__tests__/ProjectLeakPeriodInfo-test.tsx
server/sonar-web/src/main/js/apps/overview/components/LeakPeriodLegend.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingAnalysis.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/BaselineSettingReferenceBranch.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/BranchBaselineSettingModal.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/BranchList.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/BranchListRow.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineApp.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/ProjectBaselineSelector.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/ProjectBaselineApp-it.tsx
server/sonar-web/src/main/js/apps/projectBaseline/components/__tests__/utils-test.ts
server/sonar-web/src/main/js/apps/projectBaseline/constants.ts [deleted file]
server/sonar-web/src/main/js/apps/projectBaseline/utils.ts
server/sonar-web/src/main/js/apps/settings/components/NewCodePeriod.tsx
server/sonar-web/src/main/js/apps/settings/components/__tests__/NewCodePeriod-it.tsx
server/sonar-web/src/main/js/components/new-code-definition/GlobalNewCodeDefinitionDescription.tsx
server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionDaysOption.tsx
server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionPreviousVersionOption.tsx
server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionSelector.tsx
server/sonar-web/src/main/js/components/new-code-definition/NewCodeDefinitionWarning.tsx
server/sonar-web/src/main/js/helpers/__tests__/new-code-definition-test.ts [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/__tests__/new-code-period-test.ts [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/__tests__/periods-test.ts [deleted file]
server/sonar-web/src/main/js/helpers/mocks/new-code-definition.ts [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/mocks/new-code-period.ts [deleted file]
server/sonar-web/src/main/js/helpers/new-code-definition.ts [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/new-code-period.ts [new file with mode: 0644]
server/sonar-web/src/main/js/helpers/periods.ts [deleted file]
server/sonar-web/src/main/js/types/branch-like.ts
server/sonar-web/src/main/js/types/new-code-definition.ts [new file with mode: 0644]
server/sonar-web/src/main/js/types/types.ts

index 0e8506433de3d9a4c7acf2cdfbb39508db583ae0..0d429a7af6a00273388a51a8277c31840836c0b7 100644 (file)
  * 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;
   };
 
index b930d715ef2e3ece45fca40b140917ffbb9a1bfa..ca56e5f17eac3d7e2a5b3ebe43ed6f06d4b68c3d 100644 (file)
  */
 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);
 }
index 93bd5e6911ccc926eedcacf1542c857a91d907fa..dc2b236b8220e50e0a56f4f9a128c11888b5fb6d 100644 (file)
@@ -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} />
index 7b2abaa73ddbb203b0197f76ce8f5a68a23df836..1238d1e05ddbc35e196bae0475330b9c21c4e9df 100644 (file)
@@ -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,
     });
index daffdc75925644eda92f3fe6701e20487f3a928b..1b22f0b085fe21303695d7005398ba4cb983adab 100644 (file)
@@ -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);
index ddd7c3700a468172cb49880d5d9c28fd17086954..6b578e4705ea35e18fb70a728d716068cfafb23c 100644 (file)
@@ -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 }>;
index 533cf15b0745d98fd145cbe8d56510204e8a97d9..daf24ee685c85d7ff68e12a01a7b308a0c43efab 100644 (file)
@@ -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} />;
index 37d8c2ac37f0e31f29ef7d59ba17d783618ab7cf..fad0d415731f372a8e379aaf7da4f0d10f30566a 100644 (file)
@@ -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
index 4a9025ba54c0cf70ce919eaef32b20796092a529..ff14b007ff1fb8cb00dc62eeb3f423b3bc637a9c 100644 (file)
@@ -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;
index 516922ab1830d8064f9b64009c066eecc4e9329f..e03094a7ac997a6443b9dfb3cfa4abc03b14a775 100644 (file)
@@ -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();
index 3209b00b9b25548c43ccef412a8af9a3feb75b2b..a6076b2869099ed216b12aa9fa1298934c627c2b 100644 (file)
@@ -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;
     }
index ca5db89b7e02df9b966bd3c87564d8409ac5aac6..d042123ca89d5fab878c744588c9427d64bc3b22 100644 (file)
 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')}
     >
index adf4c56df1b9e651c258c13aa14f19c82c9f5118..4e9b28484af37c43ebbe94de8f0dfbc91c133bbf 100644 (file)
@@ -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')}
     >
index c60deb34b089e1f20fe36f47c8278e562ce1ba39..063a19f06399f3d0fc94c8f2a6ca063bd7982532 100644 (file)
  */
 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}
index 7d9943686e52bab330303ccf87f6897857b972ae..f8e5ab4c6ac50b70119f33eb69fd1d6ca054d6d2 100644 (file)
@@ -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}
           />
         )}
       </>
index 39197e19dd25f4cb9a664001164e660cca99f61d..401c22eac1658fd478082ccb734bff3b82e7be13 100644 (file)
@@ -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)
   );
 }
index 0b3f8674abdb27e15b8bf4a17edd337826ad95a1..5d185dd51ca91bf4079466d7690bd26d546492a9 100644 (file)
@@ -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>
               )}
index f20cc30acfc1cf134732a5d5c006bddf2a06a17d..39f6c7184212199d26fa2f243bbe3f52587fced2 100644 (file)
@@ -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}
index b10faa7cdec64e3d090dce5d6d4178c11de75b92..edcad7d025bf0ac857bece638ecbd049e6106672 100644 (file)
@@ -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',
     }),
   ]);
index c9b2640b83c377ae07ed7f2ddb9354913f0d1b1e..1f50739f93c1bee5856f173a41cfd70ce7a71040 100644 (file)
@@ -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/constants.ts b/server/sonar-web/src/main/js/apps/projectBaseline/constants.ts
deleted file mode 100644 (file)
index 00c2c82..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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 { NewCodePeriodSettingType } from '../../types/types';
-
-export const DEFAULT_GENERAL_SETTING_TYPE: NewCodePeriodSettingType =
-  NewCodePeriodSettingType.PREVIOUS_VERSION;
index f1dc41c70567ae6e69acf6c647d80bd44891adb5..6a1076de85bcb200954ca71a34462025c1b63f78 100644 (file)
@@ -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 };
 }
index 96498f2fd8a1639b67160cf2233afb95796a4b2e..7dd692db76f7eedc5970e5d2f685b4076cbe23c7 100644 (file)
@@ -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}
index f8aba024f2efafeafbcd10ef09f1793919538c2a..e541c4e645ff13ddaf46a34695bdade6395febe0 100644 (file)
@@ -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();
index cf41e0236f64c5aa29dea807bc9d1ad773ea840a..b8d3ad3898c5a4ee2b08fcf97af7a71e3a216f59 100644 (file)
 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 ?? '?'
index 3d9511bbfc0428463ac9e9dc913bb0e4b4fad2db..a3b52e9f64274987250c63d699c1d9ecdc29a3a6 100644 (file)
  */
 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
index ec113fb06a142496d34dfa0b505c1ea714a50250..60141f592e79cb120d3c6a4677adb874f9b4cdc8 100644 (file)
  */
 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') +
index ef28eeff0feaf342aaa26e10da6fb8c4ae9a61c0..4a12a6a042a55f536fccb7d6457966dc2ba624fb 100644 (file)
 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>
index dfbc9c9f503b8d29eef7ba050e303923bf11b929..60e23dcecaee2cc32125c2c2fb30155ae0da22b2 100644 (file)
 
 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 (file)
index 0000000..7368b3c
--- /dev/null
@@ -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__/new-code-period-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/new-code-period-test.ts
new file mode 100644 (file)
index 0000000..5201186
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * 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 { NewCodeDefinitionType } from '../../types/new-code-definition';
+import { getNewCodePeriodLabel } from '../new-code-period';
+import { mockPeriod } from '../testMocks';
+
+const formatter = jest.fn((v) => v);
+
+beforeEach(() => {
+  formatter.mockClear();
+});
+
+describe('getPeriodLabel', () => {
+  it('should handle missing value', () => {
+    expect(getNewCodePeriodLabel(undefined, formatter)).toBeUndefined();
+  });
+
+  it('should handle date', () => {
+    expect(getNewCodePeriodLabel(mockPeriod({ mode: 'date' }), formatter)).toBe(
+      'overview.period.date.'
+    );
+    expect(
+      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(getNewCodePeriodLabel(mockPeriod({ mode: 'days', modeParam: '12' }), formatter)).toBe(
+      'overview.period.days.12'
+    );
+    expect(formatter).not.toHaveBeenCalled();
+  });
+
+  it('should handle previous analysis', () => {
+    expect(
+      getNewCodePeriodLabel(
+        mockPeriod({ mode: 'previous_analysis', parameter: 'param' }),
+        formatter
+      )
+    ).toBe('overview.period.previous_analysis.param');
+    expect(formatter).not.toHaveBeenCalled();
+  });
+
+  it('should handle previous version', () => {
+    expect(getNewCodePeriodLabel(mockPeriod({ mode: 'previous_version' }), formatter)).toBe(
+      'overview.period.previous_version_only_date'
+    );
+    expect(
+      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(
+      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(
+      getNewCodePeriodLabel(
+        mockPeriod({ mode: 'manual_baseline', modeParam: 'A658678DE' }),
+        formatter
+      )
+    ).toBe('overview.period.manual_baseline.A658678DE');
+    expect(getNewCodePeriodLabel(mockPeriod({ mode: 'manual_baseline' }), formatter)).toBe(
+      'overview.period.manual_baseline.2019-04-23T02:12:32+0100'
+    );
+    expect(formatter).toHaveBeenCalledTimes(1);
+  });
+
+  it('should handle SPECIFIC_ANALYSIS', () => {
+    expect(
+      getNewCodePeriodLabel(
+        mockPeriod({ mode: NewCodeDefinitionType.SpecificAnalysis, parameter: '7.1' }),
+        formatter
+      )
+    ).toBe('overview.period.specific_analysis.2019-04-23T02:12:32+0100');
+    expect(
+      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(
+      getNewCodePeriodLabel(
+        mockPeriod({ mode: NewCodeDefinitionType.PreviousVersion, modeParam: 'A658678DE' }),
+        formatter
+      )
+    ).toBe('overview.period.previous_version.A658678DE');
+    expect(
+      getNewCodePeriodLabel(mockPeriod({ mode: NewCodeDefinitionType.PreviousVersion }), formatter)
+    ).toBe('overview.period.previous_version.2019-04-23T02:12:32+0100');
+    expect(formatter).toHaveBeenCalledTimes(1);
+  });
+});
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/periods-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/periods-test.ts
deleted file mode 100644 (file)
index aca6974..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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 { NewCodePeriod, NewCodePeriodSettingType } from '../../types/types';
-import { getPeriodLabel, isNewCodeDefinitionCompliant } from '../periods';
-import { mockPeriod } from '../testMocks';
-
-const formatter = jest.fn((v) => v);
-
-beforeEach(() => {
-  formatter.mockClear();
-});
-
-describe('getPeriodLabel', () => {
-  it('should handle missing value', () => {
-    expect(getPeriodLabel(undefined, formatter)).toBeUndefined();
-  });
-
-  it('should handle date', () => {
-    expect(getPeriodLabel(mockPeriod({ mode: 'date' }), formatter)).toBe('overview.period.date.');
-    expect(
-      getPeriodLabel(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(
-      'overview.period.days.12'
-    );
-    expect(formatter).not.toHaveBeenCalled();
-  });
-
-  it('should handle previous analysis', () => {
-    expect(
-      getPeriodLabel(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(
-      'overview.period.previous_version_only_date'
-    );
-    expect(
-      getPeriodLabel(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)
-    ).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)
-    ).toBe('overview.period.manual_baseline.A658678DE');
-    expect(getPeriodLabel(mockPeriod({ mode: 'manual_baseline' }), formatter)).toBe(
-      'overview.period.manual_baseline.2019-04-23T02:12:32+0100'
-    );
-    expect(formatter).toHaveBeenCalledTimes(1);
-  });
-
-  it('should handle SPECIFIC_ANALYSIS', () => {
-    expect(
-      getPeriodLabel(
-        mockPeriod({ mode: NewCodePeriodSettingType.SPECIFIC_ANALYSIS, parameter: '7.1' }),
-        formatter
-      )
-    ).toBe('overview.period.specific_analysis.2019-04-23T02:12:32+0100');
-    expect(
-      getPeriodLabel(mockPeriod({ mode: NewCodePeriodSettingType.SPECIFIC_ANALYSIS }), 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' }),
-        formatter
-      )
-    ).toBe('overview.period.previous_version.A658678DE');
-    expect(
-      getPeriodLabel(mockPeriod({ mode: NewCodePeriodSettingType.PREVIOUS_VERSION }), 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-definition.ts b/server/sonar-web/src/main/js/helpers/mocks/new-code-definition.ts
new file mode 100644 (file)
index 0000000..72ecf4f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * 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,
+  NewCodeDefinitionBranch,
+  NewCodeDefinitionType,
+} from '../../types/new-code-definition';
+
+export function mockNewCodePeriod(overrides: Partial<NewCodeDefinition> = {}): NewCodeDefinition {
+  return {
+    type: NewCodeDefinitionType.PreviousVersion,
+    ...overrides,
+  };
+}
+
+export function mockNewCodePeriodBranch(
+  overrides: Partial<NewCodeDefinitionBranch> = {}
+): NewCodeDefinitionBranch {
+  return {
+    projectKey: 'pkey',
+    branchKey: 'bKey',
+    ...mockNewCodePeriod(),
+    ...overrides,
+  };
+}
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-period.ts
deleted file mode 100644 (file)
index a437262..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * 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 { NewCodePeriod, NewCodePeriodBranch, NewCodePeriodSettingType } from '../../types/types';
-
-export function mockNewCodePeriod(overrides: Partial<NewCodePeriod> = {}) {
-  return {
-    type: NewCodePeriodSettingType.PREVIOUS_VERSION,
-    ...overrides,
-  };
-}
-
-export function mockNewCodePeriodBranch(overrides: Partial<NewCodePeriodBranch> = {}) {
-  return {
-    projectKey: 'pkey',
-    branchKey: 'bKey',
-    ...mockNewCodePeriod(),
-    ...overrides,
-  };
-}
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 (file)
index 0000000..d02b874
--- /dev/null
@@ -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/new-code-period.ts b/server/sonar-web/src/main/js/helpers/new-code-period.ts
new file mode 100644 (file)
index 0000000..7d92c95
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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 { ApplicationPeriod } from '../types/application';
+import { NewCodeDefinitionType } from '../types/new-code-definition';
+import { Period } from '../types/types';
+import { parseDate } from './dates';
+import { translate, translateWithParameters } from './l10n';
+
+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
+) {
+  if (!period) {
+    return undefined;
+  }
+
+  let parameter = period.modeParam || period.parameter || '';
+
+  switch (period.mode) {
+    case NewCodeDefinitionType.SpecificAnalysis:
+      parameter = dateFormatter(period.date);
+      break;
+    case NewCodeDefinitionType.PreviousVersion:
+      parameter = parameter || dateFormatter(period.date);
+      break;
+    /*
+     * Handle legacy period modes, that predate MMF-1579
+     */
+    case 'previous_version':
+      if (!parameter) {
+        return translate('overview.period.previous_version_only_date');
+      }
+      break;
+    case 'date':
+      parameter = parameter && dateFormatter(parameter);
+      break;
+    case 'manual_baseline':
+      parameter = parameter || dateFormatter(period.date);
+      break;
+    default: // No change in the parameter
+  }
+
+  return translateWithParameters(`overview.period.${period.mode.toLowerCase()}`, parameter);
+}
+
+export function isApplicationNewCodePeriod(
+  period: Period | ApplicationPeriod
+): period is ApplicationPeriod {
+  return (period as ApplicationPeriod).project !== undefined;
+}
diff --git a/server/sonar-web/src/main/js/helpers/periods.ts b/server/sonar-web/src/main/js/helpers/periods.ts
deleted file mode 100644 (file)
index 7e80ce8..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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 { parseDate } from '../helpers/dates';
-import { translate, translateWithParameters } from '../helpers/l10n';
-import { ApplicationPeriod } from '../types/application';
-import { NewCodePeriod, NewCodePeriodSettingType, Period } from '../types/types';
-
-export function getPeriodLabel(
-  period: Period | undefined,
-  dateFormatter: (date: string) => string
-) {
-  if (!period) {
-    return undefined;
-  }
-
-  let parameter = period.modeParam || period.parameter || '';
-
-  switch (period.mode) {
-    case NewCodePeriodSettingType.SPECIFIC_ANALYSIS:
-      parameter = dateFormatter(period.date);
-      break;
-    case NewCodePeriodSettingType.PREVIOUS_VERSION:
-      parameter = parameter || dateFormatter(period.date);
-      break;
-    /*
-     * Handle legacy period modes, that predate MMF-1579
-     */
-    case 'previous_version':
-      if (!parameter) {
-        return translate('overview.period.previous_version_only_date');
-      }
-      break;
-    case 'date':
-      parameter = parameter && dateFormatter(parameter);
-      break;
-    case 'manual_baseline':
-      parameter = parameter || dateFormatter(period.date);
-      break;
-    default: // No change in the parameter
-  }
-
-  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(
-  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;
-  }
-}
index f25c8a11693eda56a594cb7de13ca7fce488d5ec..6f1056dcf6b1c763a252a41cc188450624a00566 100644 (file)
@@ -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/types/new-code-definition.ts b/server/sonar-web/src/main/js/types/new-code-definition.ts
new file mode 100644 (file)
index 0000000..9bda3b5
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+export enum NewCodeDefinitionType {
+  PreviousVersion = 'PREVIOUS_VERSION',
+  NumberOfDays = 'NUMBER_OF_DAYS',
+  SpecificAnalysis = 'SPECIFIC_ANALYSIS',
+  ReferenceBranch = 'REFERENCE_BRANCH',
+  Inherited = 'INHERITED',
+}
+
+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;
+}
index f31661e0c7f551e4774a6da44e44ea31b03a51b9..a83e6bb36c8216ed573f594269e3eccea6a6c289 100644 (file)
@@ -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;
 }