]> source.dussan.org Git - sonarqube.git/blob
1fc2a7e95b4245985ccf83a1cef2e3f65d6c1938
[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   const renderMonoRepoFieldWithDocLink = (docLink: string) => {
155     return renderMonoRepoField({
156       monorepoEnabled,
157       value: monorepo,
158       docLink,
159       onFieldChange: props.onFieldChange
160     });
161   };
162
163   switch (alm) {
164     case AlmKeys.Azure:
165       return (
166         <>
167           {renderField({
168             help: true,
169             id: 'azure.project',
170             onFieldChange: props.onFieldChange,
171             propKey: 'slug',
172             value: slug || ''
173           })}
174           {renderField({
175             help: true,
176             id: 'azure.repository',
177             onFieldChange: props.onFieldChange,
178             propKey: 'repository',
179             value: repository || ''
180           })}
181           {renderMonoRepoFieldWithDocLink('/documentation/analysis/azuredevops-integration/')}
182         </>
183       );
184     case AlmKeys.Bitbucket:
185       return (
186         <>
187           {renderField({
188             help: true,
189             helpParams: {
190               example: (
191                 <>
192                   {'.../projects/'}
193                   <strong>{'{KEY}'}</strong>
194                   {'/repos/{SLUG}/browse'}
195                 </>
196               )
197             },
198             id: 'bitbucket.repository',
199             onFieldChange: props.onFieldChange,
200             propKey: 'repository',
201             value: repository || ''
202           })}
203           {renderField({
204             help: true,
205             helpParams: {
206               example: (
207                 <>
208                   {'.../projects/{KEY}/repos/'}
209                   <strong>{'{SLUG}'}</strong>
210                   {'/browse'}
211                 </>
212               )
213             },
214             id: 'bitbucket.slug',
215             onFieldChange: props.onFieldChange,
216             propKey: 'slug',
217             value: slug || ''
218           })}
219           {renderMonoRepoFieldWithDocLink('/documentation/analysis/bitbucket-integration/')}
220         </>
221       );
222     case AlmKeys.GitHub:
223       return (
224         <>
225           {renderField({
226             help: true,
227             helpParams: { example: 'SonarSource/sonarqube' },
228             id: 'github.repository',
229             onFieldChange: props.onFieldChange,
230             propKey: 'repository',
231             value: repository || ''
232           })}
233           {renderBooleanField({
234             help: true,
235             id: 'github.summary_comment_setting',
236             onFieldChange: props.onFieldChange,
237             propKey: 'summaryCommentEnabled',
238             value: summaryCommentEnabled === undefined ? true : summaryCommentEnabled
239           })}
240           {renderMonoRepoFieldWithDocLink('/documentation/analysis/github-integration/')}
241         </>
242       );
243     case AlmKeys.GitLab:
244       return (
245         <>
246           {renderField({
247             id: 'gitlab.repository',
248             onFieldChange: props.onFieldChange,
249             propKey: 'repository',
250             value: repository || ''
251           })}
252           {renderMonoRepoFieldWithDocLink('/documentation/analysis/gitlab-integration/')}
253         </>
254       );
255     default:
256       return null;
257   }
258 }