CustomBotWithoutProxySettings.jsx 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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. <h2 className="admin-setting-header">{t('admin:slack_integration.custom_bot_without_proxy_integration')}</h2>
  80. <div className="d-flex justify-content-center my-5">
  81. <div className="card rounded-lg shadow border-0 w-50">
  82. <h5 className="card-title m-3"><b>Slack</b></h5>
  83. <div className="card-body p-5"></div>
  84. </div>
  85. <div className="text-center w-25 mt-5">
  86. <p className="text-secondary m-0"><small>{t('admin:slack_integration.integration_sentence.integration_is_not_complete')}</small></p>
  87. <p className="text-secondary"><small>{t('admin:slack_integration.integration_sentence.proceed_with_the_following_integration_procedure')}</small></p>
  88. <hr className="border-danger align-self-center" style={{ border: 'dashed' }}></hr>
  89. </div>
  90. <div className="card rounded-lg shadow border-0 w-50">
  91. <h5 className="card-title m-3"><b>GROWI App</b></h5>
  92. <div className="card-body p-5 text-center">
  93. <a className="btn btn-primary mb-3">WESEEK Inner Wiki</a>
  94. </div>
  95. </div>
  96. </div>
  97. <h2 className="admin-setting-header">{t('admin:slack_integration.custom_bot_without_proxy_settings')}</h2>
  98. {/* temporarily put bellow component */}
  99. <SlackGrowiBridging
  100. siteName={siteName}
  101. slackWorkSpaceName={slackWSNameInWithoutProxy}
  102. />
  103. <table className="table settings-table">
  104. <colgroup>
  105. <col className="item-name" />
  106. <col className="from-db" />
  107. <col className="from-env-vars" />
  108. </colgroup>
  109. <thead>
  110. <tr><th></th><th>Database</th><th>Environment variables</th></tr>
  111. </thead>
  112. <tbody>
  113. <tr>
  114. <th>Signing Secret</th>
  115. <td>
  116. <input
  117. className="form-control"
  118. type="text"
  119. value={slackSigningSecret || ''}
  120. onChange={e => setSlackSigningSecret(e.target.value)}
  121. />
  122. </td>
  123. <td>
  124. <input
  125. className="form-control"
  126. type="text"
  127. value={slackSigningSecretEnv || ''}
  128. readOnly
  129. />
  130. <p className="form-text text-muted">
  131. {/* eslint-disable-next-line react/no-danger */}
  132. <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACK_SIGNING_SECRET' }) }} />
  133. </p>
  134. </td>
  135. </tr>
  136. <tr>
  137. <th>Bot User OAuth Token</th>
  138. <td>
  139. <input
  140. className="form-control"
  141. type="text"
  142. value={slackBotToken || ''}
  143. onChange={e => setSlackBotToken(e.target.value)}
  144. />
  145. </td>
  146. <td>
  147. <input
  148. className="form-control"
  149. type="text"
  150. value={slackBotTokenEnv || ''}
  151. readOnly
  152. />
  153. <p className="form-text text-muted">
  154. {/* eslint-disable-next-line react/no-danger */}
  155. <small dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.use_env_var_if_empty', { variable: 'SLACK_BOT_TOKEN' }) }} />
  156. </p>
  157. </td>
  158. </tr>
  159. </tbody>
  160. </table>
  161. <AdminUpdateButtonRow onClick={updateHandler} disabled={false} />
  162. <div className="my-5 mx-3">
  163. <CustomBotWithoutProxySettingsAccordion />
  164. </div>
  165. </>
  166. );
  167. };
  168. const CustomBotWithoutProxySettingsWrapper = withUnstatedContainers(CustomBotWithoutProxySettings, [AppContainer, AdminAppContainer]);
  169. CustomBotWithoutProxySettings.propTypes = {
  170. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  171. adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
  172. };
  173. export default CustomBotWithoutProxySettingsWrapper;