SmtpSetting.jsx 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import React, { useState, useRef } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { withTranslation } from 'react-i18next';
  4. import loggerFactory from '@alias/logger';
  5. import {
  6. Modal, ModalHeader, ModalBody,
  7. } from 'reactstrap';
  8. import { withUnstatedContainers } from '../../UnstatedUtils';
  9. import { toastSuccess, toastError } from '../../../util/apiNotification';
  10. import { withLoadingSppiner } from '../../SuspenseUtils';
  11. import AppContainer from '../../../services/AppContainer';
  12. import AdminAppContainer from '../../../services/AdminAppContainer';
  13. const logger = loggerFactory('growi:smtpSettings');
  14. function SmtpSetting(props) {
  15. const { adminAppContainer, t } = props;
  16. const hostInput = useRef();
  17. const portInput = useRef();
  18. const userInput = useRef();
  19. const passwordInput = useRef();
  20. const [isInitializeValueModalOpen, setIsInitializeValueModalOpen] = useState(false);
  21. function openInitializeValueModal() {
  22. setIsInitializeValueModalOpen(true);
  23. }
  24. function closeInitializeValueModal() {
  25. setIsInitializeValueModalOpen(false);
  26. }
  27. async function submitHandler() {
  28. const { t, adminAppContainer } = props;
  29. try {
  30. await adminAppContainer.updateSmtpSettingHandler();
  31. toastSuccess(t('toaster.update_successed', { target: t('admin:app_setting.smtp_settings') }));
  32. }
  33. catch (err) {
  34. toastError(err);
  35. logger.error(err);
  36. }
  37. }
  38. async function initialize() {
  39. const { t, adminAppContainer } = props;
  40. try {
  41. const mailSettingParams = await adminAppContainer.initializeSmtpSettingHandler();
  42. toastSuccess(t('toaster.initialize_successed', { target: t('admin:app_setting.smtp_settings') }));
  43. // convert values to '' if value is null for overwriting values of inputs with refs
  44. hostInput.current.value = mailSettingParams.smtpHost || '';
  45. portInput.current.value = mailSettingParams.smtpPort || '';
  46. userInput.current.value = mailSettingParams.smtpUser || '';
  47. passwordInput.current.value = mailSettingParams.smtpPassword || '';
  48. closeInitializeValueModal();
  49. }
  50. catch (err) {
  51. toastError(err);
  52. logger.error(err);
  53. }
  54. }
  55. return (
  56. <React.Fragment>
  57. <div id="mail-smtp" className="tab-pane active mt-5">
  58. <div className="row form-group mb-5">
  59. <label className="col-md-3 col-form-label text-left">{t('admin:app_setting.smtp_settings')}</label>
  60. <div className="col-md-4">
  61. <label>{t('admin:app_setting.host')}</label>
  62. <input
  63. className="form-control"
  64. type="text"
  65. ref={hostInput}
  66. defaultValue={adminAppContainer.state.smtpHost || ''}
  67. onChange={(e) => { adminAppContainer.changeSmtpHost(e.target.value) }}
  68. />
  69. </div>
  70. <div className="col-md-2">
  71. <label>{t('admin:app_setting.port')}</label>
  72. <input
  73. className="form-control"
  74. ref={portInput}
  75. defaultValue={adminAppContainer.state.smtpPort || ''}
  76. onChange={(e) => { adminAppContainer.changeSmtpPort(e.target.value) }}
  77. />
  78. </div>
  79. </div>
  80. <div className="row form-group mb-5">
  81. <div className="col-md-3 offset-md-3">
  82. <label>{t('admin:app_setting.user')}</label>
  83. <input
  84. className="form-control"
  85. type="text"
  86. ref={userInput}
  87. defaultValue={adminAppContainer.state.smtpUser || ''}
  88. onChange={(e) => { adminAppContainer.changeSmtpUser(e.target.value) }}
  89. />
  90. </div>
  91. <div className="col-md-3">
  92. <label>{t('Password')}</label>
  93. <input
  94. className="form-control"
  95. type="password"
  96. ref={passwordInput}
  97. defaultValue={adminAppContainer.state.smtpPassword || ''}
  98. onChange={(e) => { adminAppContainer.changeSmtpPassword(e.target.value) }}
  99. />
  100. </div>
  101. </div>
  102. <div className="row my-3">
  103. <div className="offset-5">
  104. <button type="button" className="btn btn-primary" onClick={submitHandler} disabled={adminAppContainer.state.retrieveError != null}>
  105. { t('Update') }
  106. </button>
  107. </div>
  108. <div className="offset-1">
  109. <button
  110. type="button"
  111. className="btn btn-secondary"
  112. onClick={openInitializeValueModal}
  113. disabled={adminAppContainer.state.retrieveError != null}
  114. >
  115. {t('admin:app_setting.initialize_mail_settings')}
  116. </button>
  117. </div>
  118. </div>
  119. </div>
  120. <Modal isOpen={isInitializeValueModalOpen} toggle={closeInitializeValueModal} className="initialize-mail-settings">
  121. <ModalHeader tag="h4" toggle={closeInitializeValueModal} className="bg-danger text-light">
  122. {t('admin:app_setting.initialize_mail_modal_header')}
  123. </ModalHeader>
  124. <ModalBody>
  125. <div className="text-center mb-4">
  126. {t('admin:app_setting.confirm_to_initialize_mail_settings')}
  127. </div>
  128. <div className="text-center my-2">
  129. <button type="button" className="btn btn-outline-secondary mr-4" onClick={closeInitializeValueModal}>
  130. {t('Cancel')}
  131. </button>
  132. <button type="button" className="btn btn-danger" onClick={initialize}>
  133. {t('Reset')}
  134. </button>
  135. </div>
  136. </ModalBody>
  137. </Modal>
  138. </React.Fragment>
  139. );
  140. }
  141. /**
  142. * Wrapper component for using unstated
  143. */
  144. const SmtpSettingWrapper = withUnstatedContainers(withLoadingSppiner(SmtpSetting), [AppContainer, AdminAppContainer]);
  145. SmtpSetting.propTypes = {
  146. t: PropTypes.func.isRequired, // i18next
  147. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  148. adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
  149. };
  150. export default withTranslation()(SmtpSettingWrapper);