Просмотр исходного кода

Merge pull request #3690 from weseek/imprv/create-reset-button

Imprv/create reset button
Yuki Takei 4 лет назад
Родитель
Сommit
7ae963005a

+ 3 - 0
resource/locales/en_US/admin/admin.json

@@ -292,6 +292,9 @@
     "cooperation_procedure": "Cooperation procedure",
     "official_bot_settings": "Official bot Settings",
     "custom_bot_without_proxy_settings": "Custom Bot without proxy Settings",
+    "reset": "Reset",
+    "delete_slackbot_settings": "Reset Slack Bot settings",
+    "slackbot_settings_notice": "Reset",
     "accordion": {
       "create_bot": "Create Bot",
       "how_to_create_a_bot": "How to create a bot",

+ 3 - 0
resource/locales/ja_JP/admin/admin.json

@@ -289,6 +289,9 @@
     "delete": "削除",
     "cooperation_procedure": "連携手順",
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) 設定",
+    "reset":"リセット",
+    "delete_slackbot_settings": "Slack Bot 設定をリセットする",
+    "slackbot_settings_notice": "リセットします",
     "accordion": {
       "create_bot": "Bot を作成する",
       "how_to_create_a_bot": "作成方法はこちら",

+ 3 - 0
resource/locales/zh_CN/admin/admin.json

@@ -299,6 +299,9 @@
     "delete": "取消",
     "cooperation_procedure": "协作程序",
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) 设置",
+    "reset":"重置",
+    "delete_slackbot_settings": "重置 Slack Bot 设置",
+    "slackbot_settings_notice": "重置",
     "accordion": {
       "create_bot": "创建 Bot",
       "how_to_create_a_bot": "如何创建一个 Bot",

+ 18 - 20
src/client/js/components/Admin/SlackIntegration/CustomBotWithoutProxyIntegrationCard.jsx

@@ -23,25 +23,24 @@ const CustomBotWithoutProxyIntegrationCard = (props) => {
       </div>
 
       <div className="text-center w-25">
-        {props.isSlackScopeSet && (
-          <div className="mt-5">
-            <p className="text-success small">
-              <i className="fa fa-check mr-1" />
-              {t('admin:slack_integration.integration_sentence.integration_successful')}
-            </p>
-            <hr className="align-self-center admin-border-success border-success"></hr>
-          </div>
-        )}
-        {!props.isSlackScopeSet && (
-          <div className="mt-4">
-            <small
-              className="text-secondary m-0"
-                  // eslint-disable-next-line react/no-danger
-              dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.integration_sentence.integration_is_not_complete') }}
-            />
-            <hr className="align-self-center admin-border-danger border-danger"></hr>
-          </div>
-        )}
+        {/* TODO apply correct condition GW-5895 */}
+        <div className="mt-4">
+          <small
+            className="text-secondary m-0"
+                // eslint-disable-next-line react/no-danger
+            dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.integration_sentence.integration_is_not_complete') }}
+          />
+          <hr className="align-self-center admin-border-danger border-danger"></hr>
+        </div>
+
+        <div className="mt-5">
+          <p className="text-success small">
+            <i className="fa fa-check mr-1" />
+            {t('admin:slack_integration.integration_sentence.integration_successful')}
+          </p>
+          <hr className="align-self-center admin-border-success border-success"></hr>
+        </div>
+
       </div>
 
       <div className="card rounded-lg shadow border-0 w-50 admin-bot-card mb-0">
@@ -57,7 +56,6 @@ const CustomBotWithoutProxyIntegrationCard = (props) => {
 CustomBotWithoutProxyIntegrationCard.propTypes = {
   siteName: PropTypes.string.isRequired,
   slackWSNameInWithoutProxy: PropTypes.string,
-  isSlackScopeSet: PropTypes.bool.isRequired,
 };
 
 export default CustomBotWithoutProxyIntegrationCard;

+ 29 - 3
src/client/js/components/Admin/SlackIntegration/CustomBotWithoutProxySettings.jsx

@@ -4,14 +4,31 @@ import PropTypes from 'prop-types';
 import AppContainer from '../../../services/AppContainer';
 import AdminAppContainer from '../../../services/AdminAppContainer';
 import { withUnstatedContainers } from '../../UnstatedUtils';
+import { toastSuccess, toastError } from '../../../util/apiNotification';
 import CustomBotWithoutProxySettingsAccordion, { botInstallationStep } from './CustomBotWithoutProxySettingsAccordion';
 import CustomBotWithoutProxyIntegrationCard from './CustomBotWithoutProxyIntegrationCard';
+import DeleteSlackBotSettingsModal from './DeleteSlackBotSettingsModal';
 
 const CustomBotWithoutProxySettings = (props) => {
   const { appContainer } = props;
   const { t } = useTranslation();
 
   const [siteName, setSiteName] = useState('');
+  const [isDeleteConfirmModalShown, setIsDeleteConfirmModalShown] = useState(false);
+
+  const deleteSlackSettingsHandler = async() => {
+    try {
+      await appContainer.apiv3.put('/slack-integration-settings/custom-bot-without-proxy', {
+        slackSigningSecret: '',
+        slackBotToken: '',
+        currentBotType: '',
+      });
+      toastSuccess('success');
+    }
+    catch (err) {
+      toastError(err);
+    }
+  };
 
   useEffect(() => {
     const siteName = appContainer.config.crowi.title;
@@ -25,17 +42,28 @@ const CustomBotWithoutProxySettings = (props) => {
       <CustomBotWithoutProxyIntegrationCard
         siteName={siteName}
         slackWSNameInWithoutProxy={props.slackWSNameInWithoutProxy}
-        isSlackScopeSet={props.isSlackScopeSet}
       />
 
       <h2 className="admin-setting-header">{t('admin:slack_integration.custom_bot_without_proxy_settings')}</h2>
 
+      <button
+        className="mx-3 pull-right btn text-danger border-danger"
+        type="button"
+        onClick={() => setIsDeleteConfirmModalShown(true)}
+      >{t('admin:slack_integration.reset')}
+      </button>
+
       <div className="my-5 mx-3">
         <CustomBotWithoutProxySettingsAccordion
           {...props}
           activeStep={botInstallationStep.CREATE_BOT}
         />
       </div>
+      <DeleteSlackBotSettingsModal
+        isOpen={isDeleteConfirmModalShown}
+        onClose={() => setIsDeleteConfirmModalShown(false)}
+        onClickDeleteButton={deleteSlackSettingsHandler}
+      />
     </>
   );
 };
@@ -50,8 +78,6 @@ CustomBotWithoutProxySettings.propTypes = {
   slackBotToken: PropTypes.string,
   slackBotTokenEnv: PropTypes.string,
   isRgisterSlackCredentials: PropTypes.bool,
-  isConnectedToSlack: PropTypes.bool,
-  isSlackScopeSet: PropTypes.bool,
   slackWSNameInWithoutProxy: PropTypes.string,
 };
 

+ 0 - 1
src/client/js/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx

@@ -213,7 +213,6 @@ CustomBotWithoutProxySettingsAccordion.propTypes = {
   slackBotTokenEnv: PropTypes.string,
   isRegisterSlackCredentials: PropTypes.bool,
   isSendTestMessage: PropTypes.bool,
-  isConnectedToSlack: PropTypes.bool,
   fetchSlackIntegrationData: PropTypes.func,
   onSetSlackSigningSecret: PropTypes.func,
   onSetSlackBotToken: PropTypes.func,

+ 65 - 0
src/client/js/components/Admin/SlackIntegration/DeleteSlackBotSettingsModal.jsx

@@ -0,0 +1,65 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { withTranslation } from 'react-i18next';
+
+import {
+  Button, Modal, ModalHeader, ModalBody, ModalFooter,
+} from 'reactstrap';
+
+const DeleteSlackBotSettingsModal = React.memo((props) => {
+  const { t } = props;
+
+  function closeModal() {
+    if (props.onClose == null) {
+      return;
+    }
+
+    props.onClose();
+  }
+
+  function deleteSlackCredentialsHandler() {
+    if (props.onClickDeleteButton == null) {
+      return;
+    }
+    props.onClickDeleteButton();
+
+    closeModal();
+  }
+
+  function closeButtonHandler() {
+    closeModal();
+  }
+
+  return (
+    <Modal isOpen={props.isOpen} toggle={closeButtonHandler} className="page-comment-delete-modal">
+      <ModalHeader tag="h4" toggle={closeButtonHandler} className="bg-danger text-light">
+        <span>
+          <i className="icon-fw icon-fire"></i>
+          {t('admin:slack_integration.delete_slackbot_settings')}
+        </span>
+      </ModalHeader>
+      <ModalBody>
+        {t('admin:slack_integration.slackbot_settings_notice')}
+      </ModalBody>
+      <ModalFooter>
+        <Button onClick={closeButtonHandler}>{t('Cancel')}</Button>
+        <Button color="danger" onClick={deleteSlackCredentialsHandler}>
+          <i className="icon icon-fire"></i>
+          {t('Reset')}
+        </Button>
+      </ModalFooter>
+    </Modal>
+  );
+
+});
+
+DeleteSlackBotSettingsModal.propTypes = {
+  t: PropTypes.func.isRequired, // i18next
+
+  isOpen: PropTypes.bool.isRequired,
+  onClose: PropTypes.func,
+  onClickDeleteButton: PropTypes.func,
+};
+
+export default withTranslation()(DeleteSlackBotSettingsModal);

+ 2 - 25
src/client/js/components/Admin/SlackIntegration/SlackIntegration.jsx

@@ -22,32 +22,26 @@ const SlackIntegration = (props) => {
   const [slackBotToken, setSlackBotToken] = useState(null);
   const [slackSigningSecretEnv, setSlackSigningSecretEnv] = useState('');
   const [slackBotTokenEnv, setSlackBotTokenEnv] = useState('');
-  const [isConnectedToSlack, setIsConnectedToSlack] = useState(false);
   const [isRegisterSlackCredentials, setIsRegisterSlackCredentials] = useState(false);
   const [isSendTestMessage, setIsSendTestMessage] = useState(false);
   const [slackWSNameInWithoutProxy, setSlackWSNameInWithoutProxy] = useState(null);
-  const [isSlackScopeSet, setIsSlackScopeSet] = useState(false);
 
   const fetchSlackWorkSpaceNameInWithoutProxy = useCallback(async() => {
-    if (!isConnectedToSlack) {
-      return setSlackWSNameInWithoutProxy(null);
-    }
+
     try {
       const res = await appContainer.apiv3.get('/slack-integration-settings/custom-bot-without-proxy/slack-workspace-name');
       setSlackWSNameInWithoutProxy(res.data.slackWorkSpaceName);
-      setIsSlackScopeSet(true);
     }
     catch (err) {
       if (err[0].message === 'missing_scope') {
         setSlackWSNameInWithoutProxy(null);
-        setIsSlackScopeSet(false);
         toastError(err, t('admin:slack_integration.set_scope'));
       }
       else {
         toastError(err);
       }
     }
-  }, [appContainer.apiv3, isConnectedToSlack, t]);
+  }, [appContainer.apiv3, t]);
 
   const fetchSlackIntegrationData = useCallback(async() => {
     try {
@@ -55,7 +49,6 @@ const SlackIntegration = (props) => {
       const { currentBotType, customBotWithoutProxySettings } = response.data.slackBotSettingParams;
       const {
         slackSigningSecret, slackBotToken, slackSigningSecretEnvVars, slackBotTokenEnvVars,
-        isConnectedToSlack,
       } = customBotWithoutProxySettings;
 
       setCurrentBotType(currentBotType);
@@ -63,18 +56,7 @@ const SlackIntegration = (props) => {
       setSlackBotToken(slackBotToken);
       setSlackSigningSecretEnv(slackSigningSecretEnvVars);
       setSlackBotTokenEnv(slackBotTokenEnvVars);
-      setIsConnectedToSlack(isConnectedToSlack);
-
       fetchSlackWorkSpaceNameInWithoutProxy();
-
-      if (isConnectedToSlack) {
-        setIsRegisterSlackCredentials(true);
-      }
-      else {
-        setIsRegisterSlackCredentials(false);
-        setIsSendTestMessage(false);
-      }
-
     }
     catch (err) {
       toastError(err);
@@ -112,13 +94,10 @@ const SlackIntegration = (props) => {
       setSelectedBotType(null);
       toastSuccess(t('admin:slack_integration.bot_reset_successful'));
       setIsRegisterSlackCredentials(false);
-      setIsConnectedToSlack(false);
       setSlackSigningSecret(null);
       setSlackBotToken(null);
-      setIsConnectedToSlack(false);
       setIsSendTestMessage(false);
       setSlackWSNameInWithoutProxy(null);
-      setIsSlackScopeSet(false);
     }
     catch (err) {
       toastError(err);
@@ -136,8 +115,6 @@ const SlackIntegration = (props) => {
         <CustomBotWithoutProxySettings
           isSendTestMessage={isSendTestMessage}
           isRegisterSlackCredentials={isRegisterSlackCredentials}
-          isConnectedToSlack={isConnectedToSlack}
-          isSlackScopeSet={isSlackScopeSet}
           slackBotTokenEnv={slackBotTokenEnv}
           slackBotToken={slackBotToken}
           slackSigningSecretEnv={slackSigningSecretEnv}