]> source.dussan.org Git - sonarqube.git/blob
8d9b8f3b4a4cd7617a96a5d703943a9d60dbcb0d
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 import {
21   ButtonPrimary,
22   FlagErrorIcon,
23   FlagMessage,
24   FormField,
25   InputField,
26   LightPrimary,
27   Link,
28   Spinner,
29 } from 'design-system';
30 import React from 'react';
31 import { FormattedMessage } from 'react-intl';
32 import { translate } from '../../../../helpers/l10n';
33 import { AlmSettingsInstance } from '../../../../types/alm-settings';
34 import { usePersonalAccessToken } from '../usePersonalAccessToken';
35
36 interface Props {
37   almSetting: AlmSettingsInstance;
38   resetPat: boolean;
39   onPersonalAccessTokenCreated: () => void;
40 }
41
42 export default function BitbucketServerPersonalAccessTokenForm({
43   almSetting,
44   resetPat,
45   onPersonalAccessTokenCreated,
46 }: Props) {
47   const {
48     password,
49     firstConnection,
50     validationFailed,
51     touched,
52     submitting,
53     validationErrorMessage,
54     checkingPat,
55     handlePasswordChange,
56     handleSubmit,
57   } = usePersonalAccessToken(almSetting, resetPat, onPersonalAccessTokenCreated);
58
59   if (checkingPat) {
60     return <Spinner className="sw-ml-2" loading />;
61   }
62
63   const { url } = almSetting;
64   const isInvalid = validationFailed && !touched;
65   const canSubmit = Boolean(password);
66   const submitButtonDiabled = isInvalid || submitting || !canSubmit;
67
68   const errorMessage =
69     validationErrorMessage ?? translate('onboarding.create_project.pat_incorrect.bitbucket');
70
71   return (
72     <form className="sw-mt-3 sw-w-[50%]" onSubmit={handleSubmit}>
73       <LightPrimary as="h2" className="sw-heading-md">
74         {translate('onboarding.create_project.pat_form.title')}
75       </LightPrimary>
76       <LightPrimary as="p" className="sw-mt-2 sw-mb-4 sw-body-sm">
77         {translate('onboarding.create_project.pat_form.help.bitbucket')}
78       </LightPrimary>
79
80       {isInvalid && (
81         <div>
82           <FlagMessage variant="error" className="sw-mb-4">
83             <p>{errorMessage}</p>
84           </FlagMessage>
85         </div>
86       )}
87
88       {!firstConnection && (
89         <FlagMessage variant="warning">
90           <p>
91             {translate('onboarding.create_project.pat.expired.info_message')}{' '}
92             {translate('onboarding.create_project.pat.expired.info_message_contact')}
93           </p>
94         </FlagMessage>
95       )}
96
97       <FormField
98         htmlFor="personal_access_token_validation"
99         className="sw-mt-6 sw-mb-3"
100         label={translate('onboarding.create_project.enter_pat')}
101         required
102       >
103         <div>
104           <InputField
105             autoFocus
106             size="large"
107             id="personal_access_token_validation"
108             minLength={1}
109             value={password}
110             onChange={handlePasswordChange}
111             type="text"
112             isInvalid={isInvalid}
113           />
114           {isInvalid && <FlagErrorIcon className="sw-ml-2" />}
115         </div>
116       </FormField>
117
118       <div className="sw-mb-6">
119         <FlagMessage variant="info">
120           <p>
121             <FormattedMessage
122               id="onboarding.create_project.pat_help.instructions.bitbucket_server"
123               defaultMessage={translate(
124                 'onboarding.create_project.pat_help.instructions.bitbucket_server',
125               )}
126               values={{
127                 link: url ? (
128                   <Link to={`${url.replace(/\/$/, '')}/account`}>
129                     {translate(
130                       'onboarding.create_project.pat_help.instructions.bitbucket_server.link',
131                     )}
132                   </Link>
133                 ) : (
134                   translate('onboarding.create_project.pat_help.instructions.bitbucket_server.link')
135                 ),
136               }}
137             />
138           </p>
139         </FlagMessage>
140       </div>
141
142       <ButtonPrimary type="submit" disabled={submitButtonDiabled} className="sw-mb-6">
143         {translate('save')}
144       </ButtonPrimary>
145       <Spinner className="sw-ml-2" loading={submitting} />
146     </form>
147   );
148 }