]> source.dussan.org Git - sonarqube.git/blob
82482cbcbfc2749aef530cb5146c7709990a6312
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2019 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 {
22   deleteProjectAlmBinding,
23   getAlmSettings,
24   getProjectAlmBinding,
25   setProjectAlmBinding
26 } from '../../../../api/almSettings';
27 import throwGlobalError from '../../../../app/utils/throwGlobalError';
28 import PRDecorationBindingRenderer from './PRDecorationBindingRenderer';
29
30 interface Props {
31   component: T.Component;
32 }
33
34 interface State {
35   formData: T.GithubBinding;
36   hasBinding: boolean;
37   instances: T.AlmSettingsInstance[];
38   isValid: boolean;
39   loading: boolean;
40   saving: boolean;
41   success: boolean;
42 }
43
44 export default class PRDecorationBinding extends React.PureComponent<Props, State> {
45   mounted = false;
46   state: State = {
47     formData: {
48       key: '',
49       repository: ''
50     },
51     hasBinding: false,
52     instances: [],
53     isValid: false,
54     loading: true,
55     saving: false,
56     success: false
57   };
58
59   componentDidMount() {
60     this.mounted = true;
61     this.fetchDefinitions();
62   }
63
64   componentWillUnmount() {
65     this.mounted = false;
66   }
67
68   fetchDefinitions = () => {
69     const project = this.props.component.key;
70     return Promise.all([getAlmSettings(project), this.getProjectBinding(project)])
71       .then(([instances, data]) => {
72         if (this.mounted) {
73           this.setState(({ formData }) => ({
74             formData: data || formData,
75             hasBinding: Boolean(data),
76             instances,
77             isValid: this.validateForm(),
78             loading: false
79           }));
80
81           if (!data && instances.length === 1) {
82             this.handleFieldChange('key', instances[0].key);
83           }
84         }
85       })
86       .catch(() => {
87         if (this.mounted) {
88           this.setState({ loading: false });
89         }
90       });
91   };
92
93   getProjectBinding(project: string) {
94     return getProjectAlmBinding(project).catch((response: Response) => {
95       if (response && response.status === 404) {
96         return Promise.resolve(undefined);
97       }
98       return throwGlobalError(response);
99     });
100   }
101
102   catchError = () => {
103     if (this.mounted) {
104       this.setState({ saving: false });
105     }
106   };
107
108   handleReset = () => {
109     const { component } = this.props;
110     this.setState({ saving: true });
111     deleteProjectAlmBinding(component.key)
112       .then(() => {
113         if (this.mounted) {
114           this.setState({
115             formData: {
116               key: '',
117               repository: ''
118             },
119             hasBinding: false,
120             saving: false,
121             success: true
122           });
123         }
124       })
125       .catch(this.catchError);
126   };
127
128   handleSubmit = () => {
129     this.setState({ saving: true });
130     const {
131       formData: { key, repository }
132     } = this.state;
133
134     if (key && repository) {
135       setProjectAlmBinding({
136         almSetting: key,
137         project: this.props.component.key,
138         repository
139       })
140         .then(() => {
141           if (this.mounted) {
142             this.setState({
143               hasBinding: true,
144               saving: false,
145               success: true
146             });
147           }
148         })
149         .catch(this.catchError);
150     }
151   };
152
153   handleFieldChange = (id: keyof T.GithubBinding, value: string) => {
154     this.setState(({ formData: formdata }) => ({
155       formData: {
156         ...formdata,
157         [id]: value
158       },
159       isValid: this.validateForm(),
160       success: false
161     }));
162   };
163
164   validateForm = () => {
165     const { formData } = this.state;
166     return Object.values(formData).reduce(
167       (result: boolean, value) => result && Boolean(value),
168       true
169     );
170   };
171
172   render() {
173     return (
174       <PRDecorationBindingRenderer
175         onFieldChange={this.handleFieldChange}
176         onReset={this.handleReset}
177         onSubmit={this.handleSubmit}
178         {...this.state}
179       />
180     );
181   }
182 }