]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7978 Add test email configuration form to the settings page (#1216)
authorStas Vilchik <vilchiks@gmail.com>
Tue, 6 Sep 2016 15:23:12 +0000 (17:23 +0200)
committerGitHub <noreply@github.com>
Tue, 6 Sep 2016 15:23:12 +0000 (17:23 +0200)
server/sonar-web/src/main/js/api/settings.js
server/sonar-web/src/main/js/apps/settings/components/EmailForm.js [new file with mode: 0644]
server/sonar-web/src/main/js/apps/settings/components/SubCategoryDefinitionsList.js
sonar-core/src/main/resources/org/sonar/l10n/core.properties
sonar-plugin-api/src/main/java/org/sonar/api/config/EmailSettings.java

index 6792f6b081cf33bcdcb17cd51dcf2a78d1914270..266463e76da020040b981f2213d04a2d0f7f2e0b 100644 (file)
@@ -67,3 +67,9 @@ export function resetSettingValue (key, componentKey) {
   }
   return post(url, data);
 }
+
+export function sendTestEmail (to, subject, message) {
+  const url = '/api/emails/send';
+  const data = { to, subject, message };
+  return post(url, data);
+}
diff --git a/server/sonar-web/src/main/js/apps/settings/components/EmailForm.js b/server/sonar-web/src/main/js/apps/settings/components/EmailForm.js
new file mode 100644 (file)
index 0000000..8f7a5cd
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import React from 'react';
+import { translate, translateWithParameters } from '../../../helpers/l10n';
+import { sendTestEmail } from '../../../api/settings';
+import { parseError } from '../../code/utils';
+
+export default class EmailForm extends React.Component {
+  constructor (props) {
+    super(props);
+    this.state = {
+      recipient: window.SS.userEmail,
+      subject: translate('email_configuration.test.subject'),
+      message: translate('email_configuration.test.message_text'),
+      loading: false,
+      success: false,
+      error: null
+    };
+  }
+
+  handleFormSubmit (e) {
+    e.preventDefault();
+    this.setState({ success: false, error: null, loading: true });
+    const { recipient, subject, message } = this.state;
+    sendTestEmail(recipient, subject, message).then(
+        () => this.setState({ success: true, loading: false }),
+        error => parseError(error).then(message => this.setState({ error: message, loading: false }))
+    );
+  }
+
+  render () {
+    return (
+        <div className="huge-spacer-top">
+          <h3 className="spacer-bottom">{translate('email_configuration.test.title')}</h3>
+
+          <form className="display-inline-block" onSubmit={e => this.handleFormSubmit(e)}>
+            {this.state.success && (
+                <div className="alert alert-success">
+                  {translateWithParameters('email_configuration.test.email_was_sent_to_x', this.state.recipient)}
+                </div>
+            )}
+
+            {this.state.error != null && (
+                <div className="alert alert-danger">
+                  {this.state.error}
+                </div>
+            )}
+
+            <div className="modal-field">
+              <label htmlFor="test-email-to">
+                {translate('email_configuration.test.to_address')}
+                <em className="mandatory">*</em>
+              </label>
+              <input
+                  id="test-email-to"
+                  type="email"
+                  required
+                  value={this.state.recipient}
+                  disabled={this.state.loading}
+                  onChange={e => this.setState({ recipient: e.target.value })}/>
+            </div>
+            <div className="modal-field">
+              <label htmlFor="test-email-subject">
+                {translate('email_configuration.test.subject')}
+              </label>
+              <input
+                  id="test-email-subject"
+                  type="text"
+                  value={this.state.subject}
+                  disabled={this.state.loading}
+                  onChange={e => this.setState({ subject: e.target.value })}/>
+            </div>
+            <div className="modal-field">
+              <label htmlFor="test-email-message">
+                {translate('email_configuration.test.message')}
+                <em className="mandatory">*</em>
+              </label>
+              <textarea
+                  id="test-email-title"
+                  required
+                  rows="5"
+                  value={this.state.message}
+                  disabled={this.state.loading}
+                  onChange={e => this.setState({ message: e.target.value })}/>
+            </div>
+
+            <div className="text-right">
+              {this.state.loading && <i className="spacer-right spinner"/>}
+              <button disabled={this.state.loading}>{translate('email_configuration.test.send')}</button>
+            </div>
+          </form>
+        </div>
+    );
+  }
+}
index f61d6b2aa7a968efb7a7cdf205dd9948ae883c70..4a8688b40dc423e4e7f9700a4986356644612dfb 100644 (file)
@@ -22,6 +22,7 @@ import shallowCompare from 'react-addons-shallow-compare';
 import groupBy from 'lodash/groupBy';
 import sortBy from 'lodash/sortBy';
 import DefinitionsList from './DefinitionsList';
+import EmailForm from './EmailForm';
 import { getSubCategoryName, getSubCategoryDescription } from '../utils';
 
 export default class SubCategoryDefinitionsList extends React.Component {
@@ -34,6 +35,14 @@ export default class SubCategoryDefinitionsList extends React.Component {
     return shallowCompare(this, nextProps, nextState);
   }
 
+  renderEmailForm (subCategoryKey) {
+    const isEmailSettings = this.props.category === 'general' && subCategoryKey === 'email';
+    if (!isEmailSettings) {
+      return null;
+    }
+    return <EmailForm/>;
+  }
+
   render () {
     const bySubCategory = groupBy(this.props.settings, setting => setting.definition.subCategory);
     const subCategories = Object.keys(bySubCategory).map(key => ({
@@ -54,6 +63,7 @@ export default class SubCategoryDefinitionsList extends React.Component {
                     </div>
                 )}
                 <DefinitionsList settings={bySubCategory[subCategory.key]} component={this.props.component}/>
+                {this.renderEmailForm(subCategory.key)}
               </li>
           ))}
         </ul>
index dc1353f58f33f673d6f7c1751a68c583ae6b660f..cf79be08d303287310160f8aaefc057deaf757f7 100644 (file)
@@ -2048,7 +2048,7 @@ email_configuration.test.to_address_required=You must provide address where to s
 email_configuration.test.subject=Subject
 email_configuration.test.subject_text=Test Message from SonarQube
 email_configuration.test.message=Message
-email_configuration.test.message_text=This is a test message from SonarQube at
+email_configuration.test.message_text=This is a test message from SonarQube.
 email_configuration.test.send=Send Test Email
 email_configuration.test.sending=Sending Test Email
 email_configuration.test.email_was_sent_to_x=Email was sent to {0}
index 1d85fb02ccda4d271951b352f773a15ee04c5cdc..9bf0cbdc5c16c52a308d84eefcffe0f00512f18e 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.api.config;
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableList;
 import java.util.List;
+import org.sonar.api.PropertyType;
 import org.sonar.api.batch.ScannerSide;
 import org.sonar.api.ce.ComputeEngineSide;
 import org.sonar.api.server.ServerSide;
@@ -120,8 +121,8 @@ public class EmailSettings {
         .type(INTEGER)
         .build(),
       PropertyDefinition.builder(SMTP_SECURE_CONNECTION)
-        .name("Use secure connection")
-        .description("Whether to use secure connection and its type.")
+        .name("Secure connection")
+        .description("Type of secure connection. Leave empty to not use secure connection.")
         .defaultValue(SMTP_SECURE_CONNECTION_DEFAULT)
         .category(CATEGORY_GENERAL)
         .subCategory(SUBCATEGORY_EMAIL)
@@ -139,6 +140,7 @@ public class EmailSettings {
         .name("SMTP password")
         .description("Password to use with authenticated SMTP.")
         .defaultValue(SMTP_PASSWORD_DEFAULT)
+        .type(PropertyType.PASSWORD)
         .category(CATEGORY_GENERAL)
         .subCategory(SUBCATEGORY_EMAIL)
         .build(),