AppSetting.jsx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import React, { useCallback } from 'react';
  2. import { useTranslation, i18n } from 'next-i18next';
  3. import PropTypes from 'prop-types';
  4. import { i18n as i18nConfig } from '^/config/next-i18next.config';
  5. import AdminAppContainer from '~/client/services/AdminAppContainer';
  6. import { toastSuccess, toastError } from '~/client/util/toastr';
  7. import loggerFactory from '~/utils/logger';
  8. import { withUnstatedContainers } from '../../UnstatedUtils';
  9. import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
  10. const logger = loggerFactory('growi:appSettings');
  11. const AppSetting = (props) => {
  12. const { adminAppContainer } = props;
  13. const { t } = useTranslation(['admin', 'commons']);
  14. const submitHandler = useCallback(async() => {
  15. try {
  16. await adminAppContainer.updateAppSettingHandler();
  17. toastSuccess(t('commons:toaster.update_successed', { target: t('commons:headers.app_settings') }));
  18. }
  19. catch (err) {
  20. toastError(err);
  21. logger.error(err);
  22. }
  23. }, [adminAppContainer, t]);
  24. return (
  25. <React.Fragment>
  26. <div className="form-group row">
  27. <label className="text-left text-md-right col-md-3 col-form-label">{t('admin:app_setting.site_name')}</label>
  28. <div className="col-md-6">
  29. <input
  30. className="form-control"
  31. type="text"
  32. defaultValue={adminAppContainer.state.title || ''}
  33. onChange={(e) => {
  34. adminAppContainer.changeTitle(e.target.value);
  35. }}
  36. placeholder="GROWI"
  37. />
  38. <p className="form-text text-muted">{t('admin:app_setting.sitename_change')}</p>
  39. </div>
  40. </div>
  41. <div className="row form-group mb-5">
  42. <label
  43. className="text-left text-md-right col-md-3 col-form-label"
  44. >
  45. {t('admin:app_setting.confidential_name')}
  46. </label>
  47. <div className="col-md-6">
  48. <input
  49. className="form-control"
  50. type="text"
  51. defaultValue={adminAppContainer.state.confidential || ''}
  52. onChange={(e) => {
  53. adminAppContainer.changeConfidential(e.target.value);
  54. }}
  55. placeholder={t('admin:app_setting.confidential_example')}
  56. />
  57. <p className="form-text text-muted">{t('admin:app_setting.header_content')}</p>
  58. </div>
  59. </div>
  60. <div className="row form-group mb-5">
  61. <label
  62. className="text-left text-md-right col-md-3 col-form-label"
  63. >
  64. {t('admin:app_setting.default_language')}
  65. </label>
  66. <div className="col-md-6 py-2">
  67. {
  68. i18nConfig.locales.map((locale) => {
  69. if (i18n == null) { return }
  70. const fixedT = i18n.getFixedT(locale, 'admin');
  71. return (
  72. <div key={locale} className="form-check custom-radio form-check-inline">
  73. <input
  74. type="radio"
  75. id={`radioLang${locale}`}
  76. className="form-check-input"
  77. name="globalLang"
  78. value={locale}
  79. checked={adminAppContainer.state.globalLang === locale}
  80. onChange={(e) => {
  81. adminAppContainer.changeGlobalLang(e.target.value);
  82. }}
  83. />
  84. <label className="form-check-label" htmlFor={`radioLang${locale}`}>{fixedT('meta.display_name')}</label>
  85. </div>
  86. );
  87. })
  88. }
  89. </div>
  90. </div>
  91. <div className="row form-group mb-5">
  92. <label
  93. className="text-left text-md-right col-md-3 col-form-label"
  94. >
  95. {t('admin:app_setting.default_mail_visibility')}
  96. </label>
  97. <div className="col-md-6 py-2">
  98. <div className="form-check custom-radio form-check-inline">
  99. <input
  100. type="radio"
  101. id="radio-email-show"
  102. className="form-check-input"
  103. name="mailVisibility"
  104. checked={adminAppContainer.state.isEmailPublishedForNewUser === true}
  105. onChange={() => { adminAppContainer.changeIsEmailPublishedForNewUserShow(true) }}
  106. />
  107. <label className="form-check-label" htmlFor="radio-email-show">{t('commons:Show')}</label>
  108. </div>
  109. <div className="form-check custom-radio form-check-inline">
  110. <input
  111. type="radio"
  112. id="radio-email-hide"
  113. className="form-check-input"
  114. name="mailVisibility"
  115. checked={adminAppContainer.state.isEmailPublishedForNewUser === false}
  116. onChange={() => { adminAppContainer.changeIsEmailPublishedForNewUserShow(false) }}
  117. />
  118. <label className="form-check-label" htmlFor="radio-email-hide">{t('commons:Hide')}</label>
  119. </div>
  120. </div>
  121. </div>
  122. <div className="row form-group mb-5">
  123. <label
  124. className="text-left text-md-right col-md-3 col-form-label"
  125. >
  126. {/* {t('admin:app_setting.file_uploading')} */}
  127. </label>
  128. <div className="col-md-6">
  129. <div className="form-check form-check-info">
  130. <input
  131. type="checkbox"
  132. id="cbFileUpload"
  133. className="form-check-input"
  134. name="fileUpload"
  135. checked={adminAppContainer.state.fileUpload}
  136. onChange={(e) => {
  137. adminAppContainer.changeFileUpload(e.target.checked);
  138. }}
  139. />
  140. <label
  141. className="form-check-label"
  142. htmlFor="cbFileUpload"
  143. >
  144. {t('admin:app_setting.enable_files_except_image')}
  145. </label>
  146. </div>
  147. <p className="form-text text-muted">
  148. {t('admin:app_setting.attach_enable')}
  149. </p>
  150. </div>
  151. </div>
  152. <AdminUpdateButtonRow onClick={submitHandler} disabled={adminAppContainer.state.retrieveError != null} />
  153. </React.Fragment>
  154. );
  155. };
  156. /**
  157. * Wrapper component for using unstated
  158. */
  159. const AppSettingWrapper = withUnstatedContainers(AppSetting, [AdminAppContainer]);
  160. AppSetting.propTypes = {
  161. adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
  162. };
  163. export default AppSettingWrapper;