CustomBotWithoutProxySettings.jsx 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import React, { useState, useEffect, useCallback } from 'react';
  2. import { useTranslation } from 'react-i18next';
  3. import PropTypes from 'prop-types';
  4. import AppContainer from '../../../services/AppContainer';
  5. import AdminAppContainer from '../../../services/AdminAppContainer';
  6. import { withUnstatedContainers } from '../../UnstatedUtils';
  7. import { toastSuccess, toastError } from '../../../util/apiNotification';
  8. import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
  9. import SlackGrowiBridging from './SlackGrowiBridging';
  10. import CustomBotWithoutProxySettingsAccordion from './CustomBotWithoutProxySettingsAccordion';
  11. const CustomBotWithoutProxySettings = (props) => {
  12. const { appContainer, adminAppContainer } = props;
  13. const { t } = useTranslation();
  14. const [slackSigningSecret, setSlackSigningSecret] = useState('');
  15. const [slackBotToken, setSlackBotToken] = useState('');
  16. const [slackSigningSecretEnv, setSlackSigningSecretEnv] = useState('');
  17. const [slackBotTokenEnv, setSlackBotTokenEnv] = useState('');
  18. const [slackWSNameInWithoutProxy, setSlackWSNameInWithoutProxy] = useState(null);
  19. // get site name from this GROWI
  20. // eslint-disable-next-line no-unused-vars
  21. const [siteName, setSiteName] = useState('');
  22. // eslint-disable-next-line no-unused-vars
  23. const [isSetupSlackBot, setIsSetupSlackBot] = useState(null);
  24. const [isConnectedToSlack, setIsConnectedToSlack] = useState(null);
  25. const currentBotType = 'custom-bot-without-proxy';
  26. useEffect(() => {
  27. const fetchData = async() => {
  28. try {
  29. const res = await appContainer.apiv3.get('/slack-integration/custom-bot-without-proxy/slack-workspace-name');
  30. setSlackWSNameInWithoutProxy(res.data.slackWorkSpaceName);
  31. }
  32. catch (err) {
  33. toastError(err);
  34. }
  35. };
  36. setSlackWSNameInWithoutProxy(null);
  37. if (isConnectedToSlack) {
  38. fetchData();
  39. }
  40. }, [appContainer, isConnectedToSlack]);
  41. const fetchData = useCallback(async() => {
  42. try {
  43. await adminAppContainer.retrieveAppSettingsData();
  44. const res = await appContainer.apiv3.get('/slack-integration/');
  45. const {
  46. slackSigningSecret, slackBotToken, slackSigningSecretEnvVars, slackBotTokenEnvVars, isSetupSlackBot, isConnectedToSlack,
  47. } = res.data.slackBotSettingParams.customBotWithoutProxySettings;
  48. setSlackSigningSecret(slackSigningSecret);
  49. setSlackBotToken(slackBotToken);
  50. setSlackSigningSecretEnv(slackSigningSecretEnvVars);
  51. setSlackBotTokenEnv(slackBotTokenEnvVars);
  52. setSiteName(adminAppContainer.state.title);
  53. setIsSetupSlackBot(isSetupSlackBot);
  54. setIsConnectedToSlack(isConnectedToSlack);
  55. }
  56. catch (err) {
  57. toastError(err);
  58. }
  59. }, [appContainer, adminAppContainer]);
  60. useEffect(() => {
  61. fetchData();
  62. }, [fetchData]);
  63. async function updateHandler() {
  64. try {
  65. await appContainer.apiv3.put('/slack-integration/custom-bot-without-proxy', {
  66. slackSigningSecret,
  67. slackBotToken,
  68. currentBotType,
  69. });
  70. fetchData();
  71. toastSuccess(t('toaster.update_successed', { target: t('admin:slack_integration.custom_bot_without_proxy_settings') }));
  72. }
  73. catch (err) {
  74. toastError(err);
  75. }
  76. }
  77. return (
  78. <>
  79. {/* ---------------- start --------------- */}
  80. <h2 className="admin-setting-header">{t('admin:slack_integration.custom_bot_without_proxy_integration')}</h2>
  81. <div className="d-flex justify-content-center my-5">
  82. {/* カード1 */}
  83. <div className="card rounded-lg shadow border-0 w-50">
  84. <h5 className="card-title m-3"><b>Slack</b></h5>
  85. <div className="card-body p-5"></div>
  86. </div>
  87. {/* 破線 & 文字 */}
  88. <div className="text-center w-25 mt-5">
  89. <p className="text-secondary m-0"><small>連携は完了していません。</small></p>
  90. <p className="text-secondary"><small>下記の連携手順を進めてください。</small></p>
  91. <hr className="border-danger align-self-center" style={{ border: 'dashed' }}></hr>
  92. </div>
  93. {/* カード2 */}
  94. <div className="card rounded-lg shadow border-0 w-50">
  95. <h5 className="card-title m-3"><b>GROWI App</b></h5>
  96. <div className="card-body p-5 text-center">
  97. <a className="btn btn-primary mb-3">WESEEK Inner Wiki</a>
  98. </div>
  99. </div>
  100. </div>
  101. {/* ---------------- end --------------- */}
  102. <h2 className="admin-setting-header">{t('admin:slack_integration.custom_bot_without_proxy_settings')}</h2>
  103. {/* temporarily put bellow component */}
  104. <SlackGrowiBridging
  105. siteName={siteName}
  106. slackWorkSpaceName={slackWSNameInWithoutProxy}
  107. />
  108. <table className="table settings-table">
  109. <colgroup>
  110. <col className="item-name" />
  111. <col className="from-db" />
  112. <col className="from-env-vars" />
  113. </colgroup>
  114. <thead>
  115. <tr><th></th><th>Database</th><th>Environment variables</th></tr>
  116. </thead>
  117. <tbody>
  118. <tr>
  119. <th>Signing Secret</th>
  120. <td>
  121. <input
  122. className="form-control"
  123. type="text"
  124. value={slackSigningSecret || ''}
  125. onChange={e => setSlackSigningSecret(e.target.value)}
  126. />
  127. </td>
  128. <td>
  129. <input
  130. className="form-control"
  131. type="text"
  132. value={slackSigningSecretEnv || ''}
  133. readOnly
  134. />
  135. <p className="form-text text-muted">
  136. {/* eslint-disable-next-line react/no-danger */}
  137. <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACK_SIGNING_SECRET' }) }} />
  138. </p>
  139. </td>
  140. </tr>
  141. <tr>
  142. <th>Bot User OAuth Token</th>
  143. <td>
  144. <input
  145. className="form-control"
  146. type="text"
  147. value={slackBotToken || ''}
  148. onChange={e => setSlackBotToken(e.target.value)}
  149. />
  150. </td>
  151. <td>
  152. <input
  153. className="form-control"
  154. type="text"
  155. value={slackBotTokenEnv || ''}
  156. readOnly
  157. />
  158. <p className="form-text text-muted">
  159. {/* eslint-disable-next-line react/no-danger */}
  160. <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACK_BOT_TOKEN' }) }} />
  161. </p>
  162. </td>
  163. </tr>
  164. </tbody>
  165. </table>
  166. <AdminUpdateButtonRow onClick={updateHandler} disabled={false} />
  167. <div className="my-5 mx-3">
  168. <CustomBotWithoutProxySettingsAccordion />
  169. </div>
  170. </>
  171. );
  172. };
  173. const CustomBotWithoutProxySettingsWrapper = withUnstatedContainers(CustomBotWithoutProxySettings, [AppContainer, AdminAppContainer]);
  174. CustomBotWithoutProxySettings.propTypes = {
  175. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  176. adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
  177. };
  178. export default CustomBotWithoutProxySettingsWrapper;