SlackIntegration.jsx 4.6 KB

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