]> source.dussan.org Git - sonarqube.git/blob
c6d297e1564b995b90028d719940534cb183d56f
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2021 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 * as React from 'react';
21 import { FormattedMessage } from 'react-intl';
22 import { Link } from 'react-router';
23 import HelpTooltip from 'sonar-ui-common/components/controls/HelpTooltip';
24 import { Alert } from 'sonar-ui-common/components/ui/Alert';
25 import { translate } from 'sonar-ui-common/helpers/l10n';
26 import { ALM_DOCUMENTATION_PATHS } from '../../../../helpers/constants';
27 import { AlmKeys, ProjectAlmBindingResponse } from '../../../../types/alm-settings';
28 import InputForBoolean from '../inputs/InputForBoolean';
29
30 export interface AlmSpecificFormProps {
31   alm: AlmKeys;
32   formData: T.Omit<ProjectAlmBindingResponse, 'alm'>;
33   onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
34   monorepoEnabled: boolean;
35 }
36
37 interface LabelProps {
38   help?: boolean;
39   helpParams?: T.Dict<string | JSX.Element>;
40   id: string;
41   optional?: boolean;
42 }
43
44 interface CommonFieldProps extends LabelProps {
45   onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
46   propKey: keyof ProjectAlmBindingResponse;
47 }
48
49 function renderLabel(props: LabelProps) {
50   const { help, helpParams, optional, id } = props;
51   return (
52     <label className="display-flex-center" htmlFor={id}>
53       {translate('settings.pr_decoration.binding.form', id)}
54       {!optional && <em className="mandatory">*</em>}
55       {help && (
56         <HelpTooltip
57           className="spacer-left"
58           overlay={
59             <FormattedMessage
60               defaultMessage={translate('settings.pr_decoration.binding.form', id, 'help')}
61               id={`settings.pr_decoration.binding.form.${id}.help`}
62               values={helpParams}
63             />
64           }
65           placement="right"
66         />
67       )}
68     </label>
69   );
70 }
71
72 function renderBooleanField(
73   props: Omit<CommonFieldProps, 'optional'> & {
74     value: boolean;
75     inputExtra?: React.ReactNode;
76   }
77 ) {
78   const { id, value, onFieldChange, propKey, inputExtra } = props;
79   return (
80     <div className="form-field">
81       {renderLabel({ ...props, optional: true })}
82       <div className="display-flex-center">
83         <InputForBoolean
84           isDefault={true}
85           name={id}
86           onChange={v => onFieldChange(propKey, v)}
87           value={value}
88         />
89         {inputExtra}
90       </div>
91     </div>
92   );
93 }
94
95 function renderField(
96   props: CommonFieldProps & {
97     value: string;
98   }
99 ) {
100   const { id, propKey, value, onFieldChange } = props;
101   return (
102     <div className="form-field">
103       {renderLabel(props)}
104       <input
105         className="input-super-large"
106         id={id}
107         maxLength={256}
108         name={id}
109         onChange={e => onFieldChange(propKey, e.currentTarget.value)}
110         type="text"
111         value={value}
112       />
113     </div>
114   );
115 }
116
117 function renderMonoRepoField(props: {
118   monorepoEnabled: boolean;
119   value?: boolean;
120   docLink: string;
121   onFieldChange: (id: keyof ProjectAlmBindingResponse, value: string | boolean) => void;
122 }) {
123   if (!props.monorepoEnabled) {
124     return null;
125   }
126
127   return renderBooleanField({
128     help: true,
129     helpParams: {
130       doc_link: (
131         <Link to={props.docLink} target="_blank">
132           {translate('learn_more')}
133         </Link>
134       )
135     },
136     id: 'monorepo',
137     onFieldChange: props.onFieldChange,
138     propKey: 'monorepo',
139     value: props.value ?? false,
140     inputExtra: props.value && (
141       <Alert className="no-margin-bottom spacer-left" variant="warning" display="inline">
142         {translate('settings.pr_decoration.binding.form.monorepo.warning')}
143       </Alert>
144     )
145   });
146 }
147
148 export default function AlmSpecificForm(props: AlmSpecificFormProps) {
149   const {
150     alm,
151     formData: { repository, slug, summaryCommentEnabled, monorepo },
152     monorepoEnabled
153   } = props;
154
155   const renderMonoRepoFieldWithDocLink = (docLink: string) => {
156     return renderMonoRepoField({
157       monorepoEnabled,
158       value: monorepo,
159       docLink,
160       onFieldChange: props.onFieldChange
161     });
162   };
163
164   switch (alm) {
165     case AlmKeys.Azure:
166       return (
167         <>
168           {renderField({
169             help: true,
170             id: 'azure.project',
171             onFieldChange: props.onFieldChange,
172             propKey: 'slug',
173             value: slug || ''
174           })}
175           {renderField({
176             help: true,
177             id: 'azure.repository',
178             onFieldChange: props.onFieldChange,
179             propKey: 'repository',
180             value: repository || ''
181           })}
182           {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.Azure])}
183         </>
184       );
185     case AlmKeys.BitbucketServer:
186       return (
187         <>
188           {renderField({
189             help: true,
190             helpParams: {
191               example: (
192                 <>
193                   {'.../projects/'}
194                   <strong>{'{KEY}'}</strong>
195                   {'/repos/{SLUG}/browse'}
196                 </>
197               )
198             },
199             id: 'bitbucket.repository',
200             onFieldChange: props.onFieldChange,
201             propKey: 'repository',
202             value: repository || ''
203           })}
204           {renderField({
205             help: true,
206             helpParams: {
207               example: (
208                 <>
209                   {'.../projects/{KEY}/repos/'}
210                   <strong>{'{SLUG}'}</strong>
211                   {'/browse'}
212                 </>
213               )
214             },
215             id: 'bitbucket.slug',
216             onFieldChange: props.onFieldChange,
217             propKey: 'slug',
218             value: slug || ''
219           })}
220           {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.BitbucketServer])}
221         </>
222       );
223     case AlmKeys.BitbucketCloud:
224       return (
225         <>
226           {renderField({
227             help: true,
228             helpParams: {
229               example: (
230                 <>
231                   {'https://bitbucket.org/{workspace}/'}
232                   <strong>{'{repository}'}</strong>
233                 </>
234               )
235             },
236             id: 'bitbucketcloud.repository',
237             onFieldChange: props.onFieldChange,
238             propKey: 'repository',
239             value: repository || ''
240           })}
241         </>
242       );
243     case AlmKeys.GitHub:
244       return (
245         <>
246           {renderField({
247             help: true,
248             helpParams: { example: 'SonarSource/sonarqube' },
249             id: 'github.repository',
250             onFieldChange: props.onFieldChange,
251             propKey: 'repository',
252             value: repository || ''
253           })}
254           {renderBooleanField({
255             help: true,
256             id: 'github.summary_comment_setting',
257             onFieldChange: props.onFieldChange,
258             propKey: 'summaryCommentEnabled',
259             value: summaryCommentEnabled === undefined ? true : summaryCommentEnabled
260           })}
261           {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.GitHub])}
262         </>
263       );
264     case AlmKeys.GitLab:
265       return (
266         <>
267           {renderField({
268             id: 'gitlab.repository',
269             onFieldChange: props.onFieldChange,
270             propKey: 'repository',
271             value: repository || ''
272           })}
273           {renderMonoRepoFieldWithDocLink(ALM_DOCUMENTATION_PATHS[AlmKeys.GitLab])}
274         </>
275       );
276     default:
277       return null;
278   }
279 }