SlackIntegration.jsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import React, { useState, useEffect, useCallback } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { useTranslation } from 'react-i18next';
  4. import AppContainer from '../../../services/AppContainer';
  5. import { withUnstatedContainers } from '../../UnstatedUtils';
  6. import { toastSuccess, toastError } from '../../../util/apiNotification';
  7. import AccessTokenSettings from './AccessTokenSettings';
  8. import OfficialBotSettings from './OfficialBotSettings';
  9. import CustomBotWithoutProxySettings from './CustomBotWithoutProxySettings';
  10. import CustomBotWithProxySettings from './CustomBotWithProxySettings';
  11. import ConfirmBotChangeModal from './ConfirmBotChangeModal';
  12. const SlackIntegration = (props) => {
  13. const { appContainer } = props;
  14. const { t } = useTranslation();
  15. const [currentBotType, setCurrentBotType] = useState(null);
  16. const [selectedBotType, setSelectedBotType] = useState(null);
  17. const fetchData = useCallback(async() => {
  18. try {
  19. const response = await appContainer.apiv3.get('slack-integration/');
  20. const { currentBotType } = response.data.slackBotSettingParams;
  21. setCurrentBotType(currentBotType);
  22. }
  23. catch (err) {
  24. toastError(err);
  25. }
  26. }, [appContainer.apiv3]);
  27. useEffect(() => {
  28. fetchData();
  29. }, [fetchData]);
  30. const resetBotType = async() => {
  31. try {
  32. await appContainer.apiv3.put('slack-integration/custom-bot-without-proxy', {
  33. slackSigningSecret: '',
  34. slackBotToken: '',
  35. botType: selectedBotType,
  36. });
  37. }
  38. catch (err) {
  39. toastError(err);
  40. }
  41. };
  42. const handleBotTypeSelect = (clickedBotType) => {
  43. if (clickedBotType === currentBotType) {
  44. return;
  45. }
  46. if (currentBotType === null) {
  47. setCurrentBotType(clickedBotType);
  48. return;
  49. }
  50. setSelectedBotType(clickedBotType);
  51. };
  52. const handleCancelBotChange = () => {
  53. setSelectedBotType(null);
  54. };
  55. const handleChangeCurrentBotSettings = async() => {
  56. try {
  57. const res = await appContainer.apiv3.put('slack-integration/custom-bot-without-proxy', {
  58. slackSigningSecret: '',
  59. slackBotToken: '',
  60. botType: selectedBotType,
  61. });
  62. setCurrentBotType(res.data.customBotWithoutProxySettingParams.slackBotType);
  63. setSelectedBotType(null);
  64. toastSuccess(t('admin:slack_integration.bot_reset_successful'));
  65. }
  66. catch (err) {
  67. toastError(err);
  68. }
  69. };
  70. let settingsComponent = null;
  71. switch (currentBotType) {
  72. case 'official-bot':
  73. settingsComponent = <OfficialBotSettings />;
  74. break;
  75. case 'custom-bot-without-proxy':
  76. settingsComponent = <CustomBotWithoutProxySettings />;
  77. break;
  78. case 'custom-bot-with-proxy':
  79. settingsComponent = <CustomBotWithProxySettings />;
  80. break;
  81. }
  82. return (
  83. <>
  84. <div className="container">
  85. <ConfirmBotChangeModal
  86. isOpen={selectedBotType != null}
  87. onConfirmClick={handleChangeCurrentBotSettings}
  88. onCancelClick={handleCancelBotChange}
  89. />
  90. </div>
  91. <div className="row">
  92. <div className="col-lg-12">
  93. <h2 className="admin-setting-header">Access Token</h2>
  94. <AccessTokenSettings />
  95. </div>
  96. </div>
  97. <div className="row my-5">
  98. <div className="card-deck mx-auto">
  99. <div
  100. className={`card admin-bot-card mx-3 py-5 rounded ${currentBotType === 'official-bot' ? 'border-info' : ''}`}
  101. onClick={() => handleBotTypeSelect('official-bot')}
  102. >
  103. <div className="card-body">
  104. <h5 className="card-title">Official Bot</h5>
  105. <p className="card-text">This is a wider card with supporting text below as a natural lead-in to additional content.</p>
  106. </div>
  107. </div>
  108. <div
  109. className={`card admin-bot-card mx-3 py-5 rounded ${currentBotType === 'custom-bot-without-proxy' ? 'border-info' : ''}`}
  110. onClick={() => handleBotTypeSelect('custom-bot-without-proxy')}
  111. >
  112. <div className="card-body">
  113. <h5 className="card-title">Custom Bot (Without Proxy)</h5>
  114. <p className="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. </p>
  115. </div>
  116. </div>
  117. <div
  118. className={`card admin-bot-card mx-3 py-5 rounded ${currentBotType === 'custom-bot-with-proxy' ? 'border-info' : ''}`}
  119. onClick={() => handleBotTypeSelect('custom-bot-with-proxy')}
  120. >
  121. <div className="card-body">
  122. <h5 className="card-title">Custom Bot (With Proxy)</h5>
  123. <p className="card-text">This is a wider card with supporting text below as a natural lead-in to additional content.</p>
  124. </div>
  125. </div>
  126. </div>
  127. </div>
  128. {settingsComponent}
  129. </>
  130. );
  131. };
  132. const SlackIntegrationWrapper = withUnstatedContainers(SlackIntegration, [AppContainer]);
  133. SlackIntegration.propTypes = {
  134. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  135. };
  136. export default SlackIntegrationWrapper;