]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-17527 Add main branch name during manual project creation
authorGuillaume Peoc'h <guillaume.peoch@sonarsource.com>
Thu, 27 Oct 2022 14:57:58 +0000 (16:57 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 1 Nov 2022 20:03:09 +0000 (20:03 +0000)
server/sonar-web/src/main/js/api/components.ts
server/sonar-web/src/main/js/apps/create/project/ManualProjectCreate.tsx
server/sonar-web/src/main/js/apps/create/project/__tests__/ManualProjectCreate-test.tsx
server/sonar-web/src/main/js/apps/projectsManagement/CreateProjectForm.tsx
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/CreateProjectForm-test.tsx
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/CreateProjectForm-test.tsx.snap [deleted file]
server/sonar-web/src/main/js/types/settings.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

index ea9c6f2621e1f2cc723df2248b240ff16229e546..d05d132b1f7605023624afd4107af92202782a9e 100644 (file)
@@ -86,6 +86,7 @@ export function deletePortfolio(portfolio: string): Promise<void | Response> {
 export function createProject(data: {
   name: string;
   project: string;
+  mainBranch: string;
   visibility?: Visibility;
 }): Promise<{ project: ProjectBase }> {
   return postJSON('/api/projects/create', data).catch(throwGlobalError);
index 696be7893d24be73dccda8d75167c15a3bd68113..480c410f267680de7e2d0891dc779487010c66ac 100644 (file)
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import classNames from 'classnames';
-import { debounce } from 'lodash';
+import { debounce, isEmpty } from 'lodash';
 import * as React from 'react';
+import { FormattedMessage } from 'react-intl';
 import { createProject, doesComponentExists } from '../../../api/components';
+import { getValue } from '../../../api/settings';
+import DocLink from '../../../components/common/DocLink';
 import ProjectKeyInput from '../../../components/common/ProjectKeyInput';
 import { SubmitButton } from '../../../components/controls/buttons';
 import ValidationInput from '../../../components/controls/ValidationInput';
@@ -30,6 +33,7 @@ import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsEx
 import { translate } from '../../../helpers/l10n';
 import { PROJECT_KEY_INVALID_CHARACTERS, validateProjectKey } from '../../../helpers/projects';
 import { ProjectKeyValidationResult } from '../../../types/component';
+import { GlobalSettingKeys } from '../../../types/settings';
 import { PROJECT_NAME_MAX_LEN } from './constants';
 import CreateProjectPageHeader from './CreateProjectPageHeader';
 import './ManualProjectCreate.css';
@@ -47,6 +51,9 @@ interface State {
   projectKeyError?: string;
   projectKeyTouched: boolean;
   validatingProjectKey: boolean;
+  mainBranchName: string;
+  mainBranchNameError?: string;
+  mainBranchNameTouched: boolean;
   submitting: boolean;
 }
 
@@ -63,6 +70,8 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat
       submitting: false,
       projectKeyTouched: false,
       projectNameTouched: false,
+      mainBranchName: 'main',
+      mainBranchNameTouched: false,
       validatingProjectKey: false
     };
     this.checkFreeKey = debounce(this.checkFreeKey, 250);
@@ -70,12 +79,21 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat
 
   componentDidMount() {
     this.mounted = true;
+    this.fetchMainBranchName();
   }
 
   componentWillUnmount() {
     this.mounted = false;
   }
 
+  fetchMainBranchName = async () => {
+    const mainBranchName = await getValue({ key: GlobalSettingKeys.MainBranchName });
+
+    if (this.mounted && mainBranchName.value !== undefined) {
+      this.setState({ mainBranchName: mainBranchName.value });
+    }
+  };
+
   checkFreeKey = (key: string) => {
     this.setState({ validatingProjectKey: true });
 
@@ -98,23 +116,25 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat
   };
 
   canSubmit(state: State): state is ValidState {
-    const { projectKey, projectKeyError, projectName, projectNameError } = state;
+    const { projectKey, projectKeyError, projectName, projectNameError, mainBranchName } = state;
     return Boolean(
       projectKeyError === undefined &&
         projectNameError === undefined &&
-        projectKey.length > 0 &&
-        projectName.length > 0
+        !isEmpty(projectKey) &&
+        !isEmpty(projectName) &&
+        !isEmpty(mainBranchName)
     );
   }
 
   handleFormSubmit = (event: React.FormEvent<HTMLFormElement>) => {
     event.preventDefault();
-    const { state } = this;
-    if (this.canSubmit(state)) {
+    const { projectKey, projectName, mainBranchName } = this.state;
+    if (this.canSubmit(this.state)) {
       this.setState({ submitting: true });
       createProject({
-        project: state.projectKey,
-        name: (state.projectName || state.projectKey).trim()
+        project: projectKey,
+        name: (projectName || projectKey).trim(),
+        mainBranch: mainBranchName
       }).then(
         ({ project }) => this.props.onProjectCreate(project.key),
         () => {
@@ -158,6 +178,14 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat
     );
   };
 
+  handleBranchNameChange = (mainBranchName: string, fromUI = false) => {
+    this.setState({
+      mainBranchName,
+      mainBranchNameError: this.validateMainBranchName(mainBranchName),
+      mainBranchNameTouched: fromUI
+    });
+  };
+
   validateKey = (projectKey: string) => {
     const result = validateProjectKey(projectKey);
     return result === ProjectKeyValidationResult.Valid
@@ -166,12 +194,19 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat
   };
 
   validateName = (projectName: string) => {
-    if (projectName.length === 0) {
+    if (isEmpty(projectName)) {
       return translate('onboarding.create_project.display_name.error.empty');
     }
     return undefined;
   };
 
+  validateMainBranchName = (mainBranchName: string) => {
+    if (isEmpty(mainBranchName)) {
+      return translate('onboarding.create_project.main_branch_name.error.empty');
+    }
+    return undefined;
+  };
+
   render() {
     const {
       projectKey,
@@ -181,13 +216,18 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat
       projectNameError,
       projectNameTouched,
       validatingProjectKey,
+      mainBranchName,
+      mainBranchNameError,
+      mainBranchNameTouched,
       submitting
     } = this.state;
     const { branchesEnabled } = this.props;
 
-    const touched = !!(projectKeyTouched || projectNameTouched);
+    const touched = Boolean(projectKeyTouched || projectNameTouched);
     const projectNameIsInvalid = projectNameTouched && projectNameError !== undefined;
     const projectNameIsValid = projectNameTouched && projectNameError === undefined;
+    const mainBranchNameIsValid = mainBranchNameTouched && mainBranchNameError === undefined;
+    const mainBranchNameIsInvalid = mainBranchNameTouched && mainBranchNameError !== undefined;
 
     return (
       <>
@@ -230,6 +270,42 @@ export default class ManualProjectCreate extends React.PureComponent<Props, Stat
                 validating={validatingProjectKey}
               />
 
+              <ValidationInput
+                className="form-field"
+                description={
+                  <FormattedMessage
+                    id="onboarding.create_project.main_branch_name.description"
+                    defaultMessage={translate(
+                      'onboarding.create_project.main_branch_name.description'
+                    )}
+                    values={{
+                      learn_more: (
+                        <DocLink to="/project-administration/project-existence">
+                          {translate('learn_more')}
+                        </DocLink>
+                      )
+                    }}
+                  />
+                }
+                error={mainBranchNameError}
+                id="main-branch-name"
+                isInvalid={mainBranchNameIsInvalid}
+                isValid={mainBranchNameIsValid}
+                label={translate('onboarding.create_project.main_branch_name')}
+                required={true}>
+                <input
+                  id="main-branch-name"
+                  className={classNames('input-super-large', {
+                    'is-invalid': mainBranchNameIsInvalid,
+                    'is-valid': mainBranchNameIsValid
+                  })}
+                  minLength={1}
+                  onChange={e => this.handleBranchNameChange(e.currentTarget.value, true)}
+                  type="text"
+                  value={mainBranchName}
+                />
+              </ValidationInput>
+
               <SubmitButton disabled={!this.canSubmit(this.state) || submitting}>
                 {translate('set_up')}
               </SubmitButton>
index 933d45fa607fa05fbef9fb3e6bd9a0c53fc48fbe..de813558a764037c394f462c9b6fd951c5793382 100644 (file)
@@ -31,6 +31,10 @@ jest.mock('../../../../api/components', () => ({
     .mockImplementation(({ component }) => Promise.resolve(component === 'exists'))
 }));
 
+jest.mock('../../../../api/settings', () => ({
+  getValue: jest.fn().mockResolvedValue({ value: 'main' })
+}));
+
 beforeEach(() => {
   jest.clearAllMocks();
 });
@@ -70,12 +74,11 @@ it('should validate form input', async () => {
   ).toHaveValue('This-is-not-a-key-');
 
   // Clear name
-  await user.click(
-    await screen.findByRole('textbox', {
+  await user.clear(
+    screen.getByRole('textbox', {
       name: 'onboarding.create_project.display_name field_required'
     })
   );
-  await user.keyboard('{Control>}a{/Control}{Backspace}');
   expect(
     screen.getByRole('textbox', { name: 'onboarding.create_project.project_key field_required' })
   ).toHaveValue('');
@@ -117,6 +120,16 @@ it('should validate form input', async () => {
   expect(
     await screen.findByText('onboarding.create_project.project_key.taken')
   ).toBeInTheDocument();
+
+  // Invalid main branch name
+  await user.clear(
+    screen.getByRole('textbox', {
+      name: 'onboarding.create_project.main_branch_name field_required'
+    })
+  );
+  expect(
+    await screen.findByText('onboarding.create_project.main_branch_name.error.empty')
+  ).toBeInTheDocument();
 });
 
 it('should submit form input', async () => {
@@ -132,7 +145,11 @@ it('should submit form input', async () => {
   );
   await user.keyboard('test');
   await user.click(screen.getByRole('button', { name: 'set_up' }));
-  expect(createProject).toHaveBeenCalledWith({ name: 'test', project: 'test' });
+  expect(createProject).toHaveBeenCalledWith({
+    name: 'test',
+    project: 'test',
+    mainBranch: 'main'
+  });
   expect(onProjectCreate).toHaveBeenCalled();
 });
 
index c25cdf0455e7f3abd20771edc425957777839870..2471f9e93ea093e4b903cbba852a317e2e9a45d7 100644 (file)
@@ -20,6 +20,7 @@
 import * as React from 'react';
 import { FormattedMessage } from 'react-intl';
 import { createProject } from '../../api/components';
+import { getValue } from '../../api/settings';
 import Link from '../../components/common/Link';
 import VisibilitySelector from '../../components/common/VisibilitySelector';
 import { ResetButtonLink, SubmitButton } from '../../components/controls/buttons';
@@ -29,6 +30,7 @@ import MandatoryFieldMarker from '../../components/ui/MandatoryFieldMarker';
 import MandatoryFieldsExplanation from '../../components/ui/MandatoryFieldsExplanation';
 import { translate } from '../../helpers/l10n';
 import { getProjectUrl } from '../../helpers/urls';
+import { GlobalSettingKeys } from '../../types/settings';
 import { Visibility } from '../../types/types';
 
 interface Props {
@@ -45,6 +47,7 @@ interface State {
   visibility?: Visibility;
   // add index declaration to be able to do `this.setState({ [name]: value });`
   [x: string]: any;
+  mainBranchName: string;
 }
 
 export default class CreateProjectForm extends React.PureComponent<Props, State> {
@@ -57,12 +60,14 @@ export default class CreateProjectForm extends React.PureComponent<Props, State>
       key: '',
       loading: false,
       name: '',
-      visibility: props.defaultProjectVisibility
+      visibility: props.defaultProjectVisibility,
+      mainBranchName: 'main'
     };
   }
 
   componentDidMount() {
     this.mounted = true;
+    this.fetchMainBranchName();
   }
 
   componentDidUpdate() {
@@ -78,6 +83,14 @@ export default class CreateProjectForm extends React.PureComponent<Props, State>
     this.mounted = false;
   }
 
+  fetchMainBranchName = async () => {
+    const mainBranchName = await getValue({ key: GlobalSettingKeys.MainBranchName });
+
+    if (this.mounted && mainBranchName.value !== undefined) {
+      this.setState({ mainBranchName: mainBranchName.value });
+    }
+  };
+
   handleInputChange = (event: React.SyntheticEvent<HTMLInputElement>) => {
     const { name, value } = event.currentTarget;
     this.setState({ [name]: value });
@@ -89,11 +102,13 @@ export default class CreateProjectForm extends React.PureComponent<Props, State>
 
   handleFormSubmit = (event: React.SyntheticEvent<HTMLFormElement>) => {
     event.preventDefault();
+    const { name, key, mainBranchName, visibility } = this.state;
 
     const data = {
-      name: this.state.name,
-      project: this.state.key,
-      visibility: this.state.visibility
+      name,
+      project: key,
+      mainBranch: mainBranchName,
+      visibility
     };
 
     this.setState({ loading: true });
@@ -159,7 +174,7 @@ export default class CreateProjectForm extends React.PureComponent<Props, State>
               <MandatoryFieldsExplanation className="modal-field" />
               <div className="modal-field">
                 <label htmlFor="create-project-name">
-                  {translate('name')}
+                  {translate('onboarding.create_project.display_name')}
                   <MandatoryFieldMarker />
                 </label>
                 <input
@@ -175,7 +190,7 @@ export default class CreateProjectForm extends React.PureComponent<Props, State>
               </div>
               <div className="modal-field">
                 <label htmlFor="create-project-key">
-                  {translate('key')}
+                  {translate('onboarding.create_project.project_key')}
                   <MandatoryFieldMarker />
                 </label>
                 <input
@@ -188,6 +203,21 @@ export default class CreateProjectForm extends React.PureComponent<Props, State>
                   value={this.state.key}
                 />
               </div>
+              <div className="modal-field">
+                <label htmlFor="create-project-main-branch-name">
+                  {translate('onboarding.create_project.main_branch_name')}
+                  <MandatoryFieldMarker />
+                </label>
+                <input
+                  id="create-project-main-branch-name"
+                  maxLength={400}
+                  name="mainBranchName"
+                  onChange={this.handleInputChange}
+                  required={true}
+                  type="text"
+                  value={this.state.mainBranchName}
+                />
+              </div>
               <div className="modal-field">
                 <label>{translate('visibility')}</label>
                 <VisibilitySelector
index 34923e19f20381b3d7760250472b67c42be1c912..328a10ee46d924e1013c72ab09547fc84c99a7c9 100644 (file)
  * along with this program; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
-/* eslint-disable import/first */
-jest.mock('../../../api/components', () => ({
-  createProject: jest.fn(({ name }: { name: string }) =>
-    Promise.resolve({ project: { key: name, name } })
-  )
-}));
 
-import { shallow } from 'enzyme';
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
 import * as React from 'react';
-import { change, submit, waitAndUpdate } from '../../../helpers/testUtils';
+import { createProject } from '../../../api/components';
 import CreateProjectForm from '../CreateProjectForm';
 
-const createProject = require('../../../api/components').createProject as jest.Mock<any>;
+jest.mock('../../../api/components', () => ({
+  createProject: jest.fn().mockResolvedValue({}),
+  doesComponentExists: jest
+    .fn()
+    .mockImplementation(({ component }) => Promise.resolve(component === 'exists'))
+}));
+
+jest.mock('../../../api/settings', () => ({
+  getValue: jest.fn().mockResolvedValue({ value: 'main' })
+}));
+
+beforeEach(() => {
+  jest.clearAllMocks();
+});
+
+it('should render all inputs and create a project', async () => {
+  const user = userEvent.setup();
+  renderCreateProjectForm();
 
-it('creates project', async () => {
-  const wrapper = shallow(
-    <CreateProjectForm
-      defaultProjectVisibility="public"
-      onClose={jest.fn()}
-      onProjectCreated={jest.fn()}
-    />
+  await user.type(
+    screen.getByRole('textbox', {
+      name: 'onboarding.create_project.display_name field_required'
+    }),
+    'ProjectName'
   );
-  (wrapper.instance() as CreateProjectForm).mounted = true;
-  expect(wrapper).toMatchSnapshot();
 
-  change(wrapper.find('input[name="name"]'), 'name', {
-    currentTarget: { name: 'name', value: 'name' }
-  });
-  change(wrapper.find('input[name="key"]'), 'key', {
-    currentTarget: { name: 'key', value: 'key' }
-  });
-  wrapper.find('VisibilitySelector').prop<Function>('onChange')('private');
-  wrapper.update();
-  expect(wrapper).toMatchSnapshot();
+  await user.type(
+    screen.getByRole('textbox', {
+      name: 'onboarding.create_project.project_key field_required'
+    }),
+    'ProjectKey'
+  );
+
+  expect(
+    screen.getByRole('textbox', {
+      name: 'onboarding.create_project.main_branch_name field_required'
+    })
+  ).toHaveValue('main');
 
-  submit(wrapper.find('form'));
+  await user.type(
+    screen.getByRole('textbox', {
+      name: 'onboarding.create_project.main_branch_name field_required'
+    }),
+    '{Control>}a{/Control}{Backspace}ProjectMainBranch'
+  );
+
+  await user.click(screen.getByRole('button', { name: 'create' }));
   expect(createProject).toHaveBeenCalledWith({
-    name: 'name',
-    project: 'key',
-    visibility: 'private'
+    name: 'ProjectName',
+    project: 'ProjectKey',
+    mainBranch: 'ProjectMainBranch'
   });
-  expect(wrapper).toMatchSnapshot();
-
-  await waitAndUpdate(wrapper);
-  expect(wrapper).toMatchSnapshot();
 });
+
+function renderCreateProjectForm(props: Partial<CreateProjectForm['props']> = {}) {
+  render(<CreateProjectForm onClose={jest.fn()} onProjectCreated={jest.fn()} {...props} />);
+}
diff --git a/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/CreateProjectForm-test.tsx.snap b/server/sonar-web/src/main/js/apps/projectsManagement/__tests__/__snapshots__/CreateProjectForm-test.tsx.snap
deleted file mode 100644 (file)
index 1a4fc25..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`creates project 1`] = `
-<Modal
-  contentLabel="modal form"
-  onRequestClose={[MockFunction]}
->
-  <form
-    id="create-project-form"
-    onSubmit={[Function]}
-  >
-    <header
-      className="modal-head"
-    >
-      <h2>
-        qualifiers.create.TRK
-      </h2>
-    </header>
-    <div
-      className="modal-body"
-    >
-      <MandatoryFieldsExplanation
-        className="modal-field"
-      />
-      <div
-        className="modal-field"
-      >
-        <label
-          htmlFor="create-project-name"
-        >
-          name
-          <MandatoryFieldMarker />
-        </label>
-        <input
-          autoFocus={true}
-          id="create-project-name"
-          maxLength={2000}
-          name="name"
-          onChange={[Function]}
-          required={true}
-          type="text"
-          value=""
-        />
-      </div>
-      <div
-        className="modal-field"
-      >
-        <label
-          htmlFor="create-project-key"
-        >
-          key
-          <MandatoryFieldMarker />
-        </label>
-        <input
-          id="create-project-key"
-          maxLength={400}
-          name="key"
-          onChange={[Function]}
-          required={true}
-          type="text"
-          value=""
-        />
-      </div>
-      <div
-        className="modal-field"
-      >
-        <label>
-          visibility
-        </label>
-        <VisibilitySelector
-          canTurnToPrivate={true}
-          className="little-spacer-top"
-          onChange={[Function]}
-          visibility="public"
-        />
-      </div>
-    </div>
-    <footer
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={false}
-        id="create-project-submit"
-      >
-        create
-      </SubmitButton>
-      <ResetButtonLink
-        id="create-project-cancel"
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </footer>
-  </form>
-</Modal>
-`;
-
-exports[`creates project 2`] = `
-<Modal
-  contentLabel="modal form"
-  onRequestClose={[MockFunction]}
->
-  <form
-    id="create-project-form"
-    onSubmit={[Function]}
-  >
-    <header
-      className="modal-head"
-    >
-      <h2>
-        qualifiers.create.TRK
-      </h2>
-    </header>
-    <div
-      className="modal-body"
-    >
-      <MandatoryFieldsExplanation
-        className="modal-field"
-      />
-      <div
-        className="modal-field"
-      >
-        <label
-          htmlFor="create-project-name"
-        >
-          name
-          <MandatoryFieldMarker />
-        </label>
-        <input
-          autoFocus={true}
-          id="create-project-name"
-          maxLength={2000}
-          name="name"
-          onChange={[Function]}
-          required={true}
-          type="text"
-          value="name"
-        />
-      </div>
-      <div
-        className="modal-field"
-      >
-        <label
-          htmlFor="create-project-key"
-        >
-          key
-          <MandatoryFieldMarker />
-        </label>
-        <input
-          id="create-project-key"
-          maxLength={400}
-          name="key"
-          onChange={[Function]}
-          required={true}
-          type="text"
-          value="key"
-        />
-      </div>
-      <div
-        className="modal-field"
-      >
-        <label>
-          visibility
-        </label>
-        <VisibilitySelector
-          canTurnToPrivate={true}
-          className="little-spacer-top"
-          onChange={[Function]}
-          visibility="private"
-        />
-      </div>
-    </div>
-    <footer
-      className="modal-foot"
-    >
-      <SubmitButton
-        disabled={false}
-        id="create-project-submit"
-      >
-        create
-      </SubmitButton>
-      <ResetButtonLink
-        id="create-project-cancel"
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </footer>
-  </form>
-</Modal>
-`;
-
-exports[`creates project 3`] = `
-<Modal
-  contentLabel="modal form"
-  onRequestClose={[MockFunction]}
->
-  <form
-    id="create-project-form"
-    onSubmit={[Function]}
-  >
-    <header
-      className="modal-head"
-    >
-      <h2>
-        qualifiers.create.TRK
-      </h2>
-    </header>
-    <div
-      className="modal-body"
-    >
-      <MandatoryFieldsExplanation
-        className="modal-field"
-      />
-      <div
-        className="modal-field"
-      >
-        <label
-          htmlFor="create-project-name"
-        >
-          name
-          <MandatoryFieldMarker />
-        </label>
-        <input
-          autoFocus={true}
-          id="create-project-name"
-          maxLength={2000}
-          name="name"
-          onChange={[Function]}
-          required={true}
-          type="text"
-          value="name"
-        />
-      </div>
-      <div
-        className="modal-field"
-      >
-        <label
-          htmlFor="create-project-key"
-        >
-          key
-          <MandatoryFieldMarker />
-        </label>
-        <input
-          id="create-project-key"
-          maxLength={400}
-          name="key"
-          onChange={[Function]}
-          required={true}
-          type="text"
-          value="key"
-        />
-      </div>
-      <div
-        className="modal-field"
-      >
-        <label>
-          visibility
-        </label>
-        <VisibilitySelector
-          canTurnToPrivate={true}
-          className="little-spacer-top"
-          onChange={[Function]}
-          visibility="private"
-        />
-      </div>
-    </div>
-    <footer
-      className="modal-foot"
-    >
-      <i
-        className="spinner spacer-right"
-      />
-      <SubmitButton
-        disabled={true}
-        id="create-project-submit"
-      >
-        create
-      </SubmitButton>
-      <ResetButtonLink
-        id="create-project-cancel"
-        onClick={[MockFunction]}
-      >
-        cancel
-      </ResetButtonLink>
-    </footer>
-  </form>
-</Modal>
-`;
-
-exports[`creates project 4`] = `
-<Modal
-  contentLabel="modal form"
-  onRequestClose={[MockFunction]}
->
-  <div>
-    <header
-      className="modal-head"
-    >
-      <h2>
-        qualifiers.create.TRK
-      </h2>
-    </header>
-    <div
-      className="modal-body"
-    >
-      <Alert
-        variant="success"
-      >
-        <FormattedMessage
-          defaultMessage="projects_management.project_has_been_successfully_created"
-          id="projects_management.project_has_been_successfully_created"
-          values={
-            Object {
-              "project": <ForwardRef(Link)
-                to={
-                  Object {
-                    "pathname": "/dashboard",
-                    "search": "?id=name",
-                  }
-                }
-              >
-                name
-              </ForwardRef(Link)>,
-            }
-          }
-        />
-      </Alert>
-    </div>
-    <footer
-      className="modal-foot"
-    >
-      <ResetButtonLink
-        id="create-project-close"
-        innerRef={[Function]}
-        onClick={[MockFunction]}
-      >
-        close
-      </ResetButtonLink>
-    </footer>
-  </div>
-</Modal>
-`;
index 32cfbc2004ac84686031319963ec4ad8fd0739c0..d1de09e3f7ffa7c532f19b8ee948c6238ba954ef 100644 (file)
@@ -38,7 +38,8 @@ export enum GlobalSettingKeys {
   DeveloperAggregatedInfoDisabled = 'sonar.developerAggregatedInfo.disabled',
   UpdatecenterActivated = 'sonar.updatecenter.activate',
   DisplayAnnouncementMessage = 'sonar.announcement.displayMessage',
-  AnnouncementMessage = 'sonar.announcement.message'
+  AnnouncementMessage = 'sonar.announcement.message',
+  MainBranchName = 'sonar.projectCreation.mainBranchName'
 }
 
 export type SettingDefinitionAndValue = {
index 763718660ab94f3bae9ba2913bdbf6da4c5fef87..2acd0079329e4c084095545b2f37c7aebc6c2848 100644 (file)
@@ -3499,6 +3499,11 @@ onboarding.create_project.project_key.taken=This project key is already taken.
 onboarding.create_project.display_name=Project display name
 onboarding.create_project.display_name.error.empty=The display name is required.
 onboarding.create_project.display_name.description=Up to 255 characters. Some scanners might override the value you provide.
+
+onboarding.create_project.main_branch_name=Main branch name
+onboarding.create_project.main_branch_name.error.empty=The main branch name is required.
+onboarding.create_project.main_branch_name.description=The name of your project’s default branch { learn_more }
+
 onboarding.create_project.pr_decoration.information=Manually created projects won’t benefit from the features associated with DevOps Platforms integration unless you configure them in the project settings.
 onboarding.create_project.repository_imported=Already set up
 onboarding.create_project.see_project=See the project