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