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

Merge branch 'feat/growi-bot' into feat/create-input-slack-ws-for-test

# Conflicts:
#	src/client/js/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx
zahmis 5 лет назад
Родитель
Сommit
92e262984c

+ 8 - 1
resource/locales/en_US/admin/admin.json

@@ -290,10 +290,17 @@
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) Settings",
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) Settings",
     "without_proxy": {
     "without_proxy": {
       "create_bot": "Create Bot",
       "create_bot": "Create Bot",
+      "how_to_create_a_bot": "How to create a bot",
       "install_bot_to_slack": "Install Bot To Slack",
       "install_bot_to_slack": "Install Bot To Slack",
+      "select_install_your_app": "Select \"Install your app\".",
+      "select_install_to_workspace": "Select \"Install to Workspace\".",
+      "click_allow": "Select \"Allow\".",
+      "install_complete_if_checked": "Confirm that \"Install your app\" is checked.",
+      "invite_bot_to_channel": "Invite GROWI bot to channel by calling @example.",
       "register_secret_and_token": "Set Signing Secret and Bot Token",
       "register_secret_and_token": "Set Signing Secret and Bot Token",
       "test_connection": "Test Connection",
       "test_connection": "Test Connection",
-      "how_to_create_a_bot": "How to create a bot"
+      "test_connection_by_pressing_button": "Press the button to test the connection",
+      "error_check_logs_below": "An error has occurred. Please check the logs below."
     },
     },
     "custom_bot_without_proxy_integration": "Custom bot without proxy integration",
     "custom_bot_without_proxy_integration": "Custom bot without proxy integration",
     "integration_sentence": {
     "integration_sentence": {

+ 32 - 25
resource/locales/ja_JP/admin/admin.json

@@ -1,5 +1,5 @@
 {
 {
-  "mailer_setup_required":"送信するには <a href='/admin/app'>メールの設定</a> が必要です。",
+  "mailer_setup_required": "送信するには <a href='/admin/app'>メールの設定</a> が必要です。",
   "admin_top": {
   "admin_top": {
     "management_wiki": "Wiki管理",
     "management_wiki": "Wiki管理",
     "system_information": "システム情報",
     "system_information": "システム情報",
@@ -9,9 +9,9 @@
     "package_name": "パッケージ名",
     "package_name": "パッケージ名",
     "specified_version": "指定バージョン",
     "specified_version": "指定バージョン",
     "installed_version": "インストールされているバージョン",
     "installed_version": "インストールされているバージョン",
-    "list_of_env_vars":"サーバー側で設定されている環境変数一覧",
-    "env_var_priority":"セキュリティに関する環境変数を除き、データベースの値が優先的に取得されます。",
-    "about_security":"セキュリティに関する環境変数は <a href='/admin/security'>セキュリティ設定画面</a> からご確認ください。"
+    "list_of_env_vars": "サーバー側で設定されている環境変数一覧",
+    "env_var_priority": "セキュリティに関する環境変数を除き、データベースの値が優先的に取得されます。",
+    "about_security": "セキュリティに関する環境変数は <a href='/admin/security'>セキュリティ設定画面</a> からご確認ください。"
   },
   },
   "app_setting": {
   "app_setting": {
     "site_name": "サイト名",
     "site_name": "サイト名",
@@ -31,9 +31,9 @@
     "mail_settings": "メールの設定",
     "mail_settings": "メールの設定",
     "mailer_is_not_set_up": "メール設定がセットアップされていません。",
     "mailer_is_not_set_up": "メール設定がセットアップされていません。",
     "from_e-mail_address": "Fromアドレス",
     "from_e-mail_address": "Fromアドレス",
-    "transmission_method":"送信方法",
-    "smtp_label":"SMTP",
-    "ses_label":"SES(AWS)",
+    "transmission_method": "送信方法",
+    "smtp_label": "SMTP",
+    "ses_label": "SES(AWS)",
     "send_test_email": "テストメールを送信",
     "send_test_email": "テストメールを送信",
     "success_to_send_test_email": "テストメールを送信しました。",
     "success_to_send_test_email": "テストメールを送信しました。",
     "smtp_settings": "SMTP設定",
     "smtp_settings": "SMTP設定",
@@ -43,20 +43,20 @@
     "initialize_mail_settings": "設定を初期化",
     "initialize_mail_settings": "設定を初期化",
     "initialize_mail_modal_header": "メール設定の初期化",
     "initialize_mail_modal_header": "メール設定の初期化",
     "confirm_to_initialize_mail_settings": "一度初期化した設定は戻せません。本当に初期化しますか?",
     "confirm_to_initialize_mail_settings": "一度初期化した設定は戻せません。本当に初期化しますか?",
-    "file_upload_settings":"ファイルアップロード設定",
-    "file_upload_method":"ファイルアップロード方法",
-    "file_delivery_method":"ファイルの配信方法",
-    "file_delivery_method_redirect":"リダイレクト",
-    "file_delivery_method_relay":"内部システム中継",
-    "file_delivery_method_redirect_info":"リダイレクト: GROWIサーバーを介さずに署名付きURLにリダイレクトされるため、優れたパフォーマンスを出します。",
-    "file_delivery_method_relay_info":"内部システム中継: GROWIサーバーがクライアントに配信するため、完全なセキュリティーを提供します。",
+    "file_upload_settings": "ファイルアップロード設定",
+    "file_upload_method": "ファイルアップロード方法",
+    "file_delivery_method": "ファイルの配信方法",
+    "file_delivery_method_redirect": "リダイレクト",
+    "file_delivery_method_relay": "内部システム中継",
+    "file_delivery_method_redirect_info": "リダイレクト: GROWIサーバーを介さずに署名付きURLにリダイレクトされるため、優れたパフォーマンスを出します。",
+    "file_delivery_method_relay_info": "内部システム中継: GROWIサーバーがクライアントに配信するため、完全なセキュリティーを提供します。",
     "gcs_label": "GCP(GCS)",
     "gcs_label": "GCP(GCS)",
     "aws_label": "AWS(S3)",
     "aws_label": "AWS(S3)",
     "local_label": "Local",
     "local_label": "Local",
     "gridfs_label": "MongoDB(GridFS)",
     "gridfs_label": "MongoDB(GridFS)",
     "fixed_by_env_var": "環境変数 <code>FILE_UPLOAD={{fileUploadType}}</code> により固定されています。",
     "fixed_by_env_var": "環境変数 <code>FILE_UPLOAD={{fileUploadType}}</code> により固定されています。",
     "file_upload": "ファイルをアップロードするための設定を行います。ファイルアップロードの設定を完了させると、ファイルアップロード機能、プロフィール写真機能などが有効になります。",
     "file_upload": "ファイルをアップロードするための設定を行います。ファイルアップロードの設定を完了させると、ファイルアップロード機能、プロフィール写真機能などが有効になります。",
-    "ses_settings":"SES設定",
+    "ses_settings": "SES設定",
     "test_connection": "接続テスト",
     "test_connection": "接続テスト",
     "change_setting": "この設定を途中で変更すると、これまでにアップロードしたファイル等へのアクセスができなくなりますのでご注意下さい。",
     "change_setting": "この設定を途中で変更すると、これまでにアップロードしたファイル等へのアクセスができなくなりますのでご注意下さい。",
     "region": "リージョン",
     "region": "リージョン",
@@ -116,7 +116,7 @@
   },
   },
   "customize_setting": {
   "customize_setting": {
     "theme": "テーマ",
     "theme": "テーマ",
-    "theme_desc" : {
+    "theme_desc": {
       "light_and_dark": "Light/Dark モード選択あり",
       "light_and_dark": "Light/Dark モード選択あり",
       "unique": "モード選択なし"
       "unique": "モード選択なし"
     },
     },
@@ -246,9 +246,9 @@
     },
     },
     "import": "インポート",
     "import": "インポート",
     "skip_username_and_email_when_overlapped": "ユーザー名またはメールアドレスが同じ場合、その部分がスキップされます。",
     "skip_username_and_email_when_overlapped": "ユーザー名またはメールアドレスが同じ場合、その部分がスキップされます。",
-    "prepare_new_account_for_migration":"移行用のアカウントを新環境で用意してください。",
-    "archive_data_import_detail":"参考: GROWI Docs - データのインポート",
-    "admin_archive_data_import_guide_url":"https://docs.growi.org/ja/admin-guide/management-cookbook/import.html#growi-%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88",
+    "prepare_new_account_for_migration": "移行用のアカウントを新環境で用意してください。",
+    "archive_data_import_detail": "参考: GROWI Docs - データのインポート",
+    "admin_archive_data_import_guide_url": "https://docs.growi.org/ja/admin-guide/management-cookbook/import.html#growi-%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96%E3%83%87%E3%83%BC%E3%82%BF%E3%82%A4%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%88",
     "page_skip": "既に GROWI 側に同名のページが存在する場合、そのページはスキップされます",
     "page_skip": "既に GROWI 側に同名のページが存在する場合、そのページはスキップされます",
     "Directory_hierarchy_tag": "ディレクトリ階層タグ"
     "Directory_hierarchy_tag": "ディレクトリ階層タグ"
   },
   },
@@ -288,10 +288,17 @@
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) 設定",
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) 設定",
     "without_proxy": {
     "without_proxy": {
       "create_bot": "Bot を作成する",
       "create_bot": "Bot を作成する",
+      "how_to_create_a_bot": "作成方法はこちら",
       "install_bot_to_slack": "Bot を Slackにインストールする",
       "install_bot_to_slack": "Bot を Slackにインストールする",
+      "select_install_your_app": "Install your app をクリックします。",
+      "select_install_to_workspace": "Install to Workspace をクリックします。",
+      "click_allow": "遷移先の画面にて、Allowをクリックします。",
+      "install_complete_if_checked": "Install your app の右側に緑色のチェックがつけばワークスペースへのインストール完了です。",
+      "invite_bot_to_channel": "GROWI bot を使いたいチャンネルに @example を使用して招待します。",
       "register_secret_and_token": "Signing Secret と Bot Token を登録する",
       "register_secret_and_token": "Signing Secret と Bot Token を登録する",
       "test_connection": "連携状況のテストをする",
       "test_connection": "連携状況のテストをする",
-      "how_to_create_a_bot": "作成方法はこちら"
+      "test_connection_by_pressing_button": "以下のテストボタンを押して、Slack連携が完了しているかの確認をしましょう",
+      "error_check_logs_below": "エラーが発生しました。下記のログを確認してください。"
     },
     },
     "custom_bot_without_proxy_integration": "Custom bot without proxy 連携",
     "custom_bot_without_proxy_integration": "Custom bot without proxy 連携",
     "integration_sentence": {
     "integration_sentence": {
@@ -305,10 +312,10 @@
     "click_twice_same_checkbox": "少なくとも一つはチェックしてください。",
     "click_twice_same_checkbox": "少なくとも一つはチェックしてください。",
     "invite_modal": {
     "invite_modal": {
       "emails": "メールアドレス (複数行入力で複数人発行可能)",
       "emails": "メールアドレス (複数行入力で複数人発行可能)",
-      "description1":"メールアドレスを使用して新規ユーザーを仮発行します。",
-      "description2":"初回のログイン時に使用する仮パスワードが生成されます。",
+      "description1": "メールアドレスを使用して新規ユーザーを仮発行します。",
+      "description2": "初回のログイン時に使用する仮パスワードが生成されます。",
       "invite_thru_email": "招待メールを送信する",
       "invite_thru_email": "招待メールを送信する",
-      "mail_setting_link":"<i class='icon-settings mr-2'></i><a href='/admin/app'>メールの設定</a>",
+      "mail_setting_link": "<i class='icon-settings mr-2'></i><a href='/admin/app'>メールの設定</a>",
       "valid_email": "メールアドレスを入力してください。",
       "valid_email": "メールアドレスを入力してください。",
       "temporary_password": "作成したユーザーは仮パスワードが設定されています。",
       "temporary_password": "作成したユーザーは仮パスワードが設定されています。",
       "send_new_password": "新規発行したパスワードを、対象ユーザーへ連絡してください。",
       "send_new_password": "新規発行したパスワードを、対象ユーザーへ連絡してください。",
@@ -338,9 +345,9 @@
     },
     },
     "external_account": "外部アカウントの管理",
     "external_account": "外部アカウントの管理",
     "external_accounts": "外部アカウント",
     "external_accounts": "外部アカウント",
-    "create_external_account":"外部アカウントの作成",
+    "create_external_account": "外部アカウントの作成",
     "external_account_list": "外部アカウント一覧",
     "external_account_list": "外部アカウント一覧",
-    "external_account_none":"外部アカウントはありません",
+    "external_account_none": "外部アカウントはありません",
     "invite": "招待する",
     "invite": "招待する",
     "invited": "ユーザーを招待しました",
     "invited": "ユーザーを招待しました",
     "back_to_user_management": "ユーザー管理に戻る",
     "back_to_user_management": "ユーザー管理に戻る",

+ 9 - 2
resource/locales/zh_CN/admin/admin.json

@@ -290,7 +290,7 @@
       "cancel": "取消",
       "cancel": "取消",
       "change": "改变"
       "change": "改变"
     },
     },
-    "use_env_var_if_empty": "如果数据库中的值为空,则环境变量的值 <cod>{{variable}}</code> 启用。",
+    "use_env_var_if_empty": "如果数据库中的值为空,则环境变量的值 <code>{{variable}}</code> 启用。",
     "access_token_settings": {
     "access_token_settings": {
       "discard": "丢弃",
       "discard": "丢弃",
       "generate": "生成"
       "generate": "生成"
@@ -298,10 +298,17 @@
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) 设置",
     "custom_bot_without_proxy_settings": "Custom Bot (Without-Proxy) 设置",
     "without_proxy": {
     "without_proxy": {
       "create_bot": "创建 Bot",
       "create_bot": "创建 Bot",
+      "how_to_create_a_bot": "如何创建一个BOT",
       "install_bot_to_slack": "将Bot安装到Slack",
       "install_bot_to_slack": "将Bot安装到Slack",
+      "select_install_your_app": "选择 \"Install your app\"。",
+      "select_install_to_workspace": "选择 \"Install to Workspace\"。",
+      "click_allow": "选择 \"Allow\"。",
+      "install_complete_if_checked": "确认已选中 \"Install your app\"。",
+      "invite_bot_to_channel": "通过调用 @example 邀请 GROWI Bot 进行频道。",
       "register_secret_and_token": "设置签名秘密和BOT令牌",
       "register_secret_and_token": "设置签名秘密和BOT令牌",
       "test_connection": "测试连接",
       "test_connection": "测试连接",
-      "how_to_create_a_bot": "如何创建一个BOT"
+      "test_connection_by_pressing_button": "按下按钮以测试连接",
+      "error_check_logs_below": "发生了错误。请检查以下日志。"
     },
     },
     "custom_bot_without_proxy_integration": "Custom bot without proxy 一体化",
     "custom_bot_without_proxy_integration": "Custom bot without proxy 一体化",
     "integration_sentence": {
     "integration_sentence": {

+ 5 - 1
src/client/js/components/Admin/Common/Accordion.jsx

@@ -29,7 +29,11 @@ const Accordion = (props) => {
 Accordion.propTypes = {
 Accordion.propTypes = {
   title: PropTypes.node.isRequired,
   title: PropTypes.node.isRequired,
   children: PropTypes.node.isRequired,
   children: PropTypes.node.isRequired,
-  isOpenDefault: PropTypes.bool.isRequired,
+  isOpenDefault: PropTypes.bool,
+};
+
+Accordion.defaultProps = {
+  isOpenDefault: false,
 };
 };
 
 
 export default Accordion;
 export default Accordion;

+ 18 - 27
src/client/js/components/Admin/SlackIntegration/CustomBotWithoutProxySettings.jsx

@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useCallback } from 'react';
+import React, { useState, useEffect } from 'react';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 import AppContainer from '../../../services/AppContainer';
 import AppContainer from '../../../services/AppContainer';
@@ -9,19 +9,20 @@ import SlackGrowiBridging from './SlackGrowiBridging';
 import CustomBotWithoutProxySettingsAccordion, { botInstallationStep } from './CustomBotWithoutProxySettingsAccordion';
 import CustomBotWithoutProxySettingsAccordion, { botInstallationStep } from './CustomBotWithoutProxySettingsAccordion';
 
 
 const CustomBotWithoutProxySettings = (props) => {
 const CustomBotWithoutProxySettings = (props) => {
-  const { appContainer, adminAppContainer } = props;
+  const { appContainer } = props;
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 
   const [slackWSNameInWithoutProxy, setSlackWSNameInWithoutProxy] = useState(null);
   const [slackWSNameInWithoutProxy, setSlackWSNameInWithoutProxy] = useState(null);
+
   // get site name from this GROWI
   // get site name from this GROWI
   // eslint-disable-next-line no-unused-vars
   // eslint-disable-next-line no-unused-vars
   const [siteName, setSiteName] = useState('');
   const [siteName, setSiteName] = useState('');
+
   // eslint-disable-next-line no-unused-vars
   // eslint-disable-next-line no-unused-vars
   const [isSetupSlackBot, setIsSetupSlackBot] = useState(null);
   const [isSetupSlackBot, setIsSetupSlackBot] = useState(null);
-  const [isConnectedToSlack, setIsConnectedToSlack] = useState(null);
 
 
   useEffect(() => {
   useEffect(() => {
-    const fetchData = async() => {
+    const getSlackWorkSpaceName = async() => {
       try {
       try {
         const res = await appContainer.apiv3.get('/slack-integration/custom-bot-without-proxy/slack-workspace-name');
         const res = await appContainer.apiv3.get('/slack-integration/custom-bot-without-proxy/slack-workspace-name');
         setSlackWSNameInWithoutProxy(res.data.slackWorkSpaceName);
         setSlackWSNameInWithoutProxy(res.data.slackWorkSpaceName);
@@ -31,28 +32,10 @@ const CustomBotWithoutProxySettings = (props) => {
       }
       }
     };
     };
     setSlackWSNameInWithoutProxy(null);
     setSlackWSNameInWithoutProxy(null);
-    if (isConnectedToSlack) {
-      fetchData();
-    }
-  }, [appContainer, isConnectedToSlack]);
-
-  const fetchData = useCallback(async() => {
-    try {
-      await adminAppContainer.retrieveAppSettingsData();
-      const res = await appContainer.apiv3.get('/slack-integration/');
-      const { isSetupSlackBot, isConnectedToSlack } = res.data.slackBotSettingParams.customBotWithoutProxySettings;
-      setSiteName(adminAppContainer.state.title);
-      setIsSetupSlackBot(isSetupSlackBot);
-      setIsConnectedToSlack(isConnectedToSlack);
+    if (props.isConnectedToSlack) {
+      getSlackWorkSpaceName();
     }
     }
-    catch (err) {
-      toastError(err);
-    }
-  }, [appContainer, adminAppContainer]);
-
-  useEffect(() => {
-    fetchData();
-  }, [fetchData]);
+  }, [appContainer, props.isConnectedToSlack]);
 
 
   return (
   return (
     <>
     <>
@@ -87,8 +70,10 @@ const CustomBotWithoutProxySettings = (props) => {
       />
       />
 
 
       <div className="my-5 mx-3">
       <div className="my-5 mx-3">
-        {/* TODO GW-5644 active create bot step temporary */}
-        <CustomBotWithoutProxySettingsAccordion activeStep={botInstallationStep.CREATE_BOT} />
+        <CustomBotWithoutProxySettingsAccordion
+          {...props}
+          activeStep={botInstallationStep.CREATE_BOT}
+        />
       </div>
       </div>
 
 
     </>
     </>
@@ -100,6 +85,12 @@ const CustomBotWithoutProxySettingsWrapper = withUnstatedContainers(CustomBotWit
 CustomBotWithoutProxySettings.propTypes = {
 CustomBotWithoutProxySettings.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
   adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
+  slackSigningSecret: PropTypes.string,
+  slackSigningSecretEnv: PropTypes.string,
+  slackBotToken: PropTypes.string,
+  slackBotTokenEnv: PropTypes.string,
+  isRgisterSlackCredentials: PropTypes.bool,
+  isConnectedToSlack: PropTypes.bool,
 };
 };
 
 
 export default CustomBotWithoutProxySettingsWrapper;
 export default CustomBotWithoutProxySettingsWrapper;

+ 40 - 46
src/client/js/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx

@@ -1,4 +1,4 @@
-import React, { useState, useEffect, useCallback } from 'react';
+import React, { useState } from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 import AppContainer from '../../../services/AppContainer';
 import AppContainer from '../../../services/AppContainer';
@@ -15,39 +15,19 @@ export const botInstallationStep = {
   CONNECTION_TEST: 'connection-test',
   CONNECTION_TEST: 'connection-test',
 };
 };
 
 
-const CustomBotWithoutProxySettingsAccordion = ({ appContainer, adminAppContainer, activeStep }) => {
-  const { t } = useTranslation('admin');
+const CustomBotWithoutProxySettingsAccordion = ({
+  appContainer,
+  activeStep, slackSigningSecret, slackSigningSecretEnv, slackBotToken,
+  slackBotTokenEnv, isRegisterSlackCredentials, isSendTestMessage,
+  setSlackSigningSecret, setSlackBotToken, setIsSendTestMessage, setIsRegisterSlackCredentials,
+}) => {
+  const { t } = useTranslation();
   // TODO: GW-5644 Store default open accordion
   // TODO: GW-5644 Store default open accordion
   // eslint-disable-next-line no-unused-vars
   // eslint-disable-next-line no-unused-vars
   const [defaultOpenAccordionKeys, setDefaultOpenAccordionKeys] = useState(new Set([activeStep]));
   const [defaultOpenAccordionKeys, setDefaultOpenAccordionKeys] = useState(new Set([activeStep]));
   const [connectionErrorCode, setConnectionErrorCode] = useState(null);
   const [connectionErrorCode, setConnectionErrorCode] = useState(null);
   const [connectionErrorMessage, setConnectionErrorMessage] = useState(null);
   const [connectionErrorMessage, setConnectionErrorMessage] = useState(null);
-  const [slackSigningSecret, setSlackSigningSecret] = useState('');
-  const [slackBotToken, setSlackBotToken] = useState('');
-  const [slackSigningSecretEnv, setSlackSigningSecretEnv] = useState('');
-  const [slackBotTokenEnv, setSlackBotTokenEnv] = useState('');
-  const currentBotType = 'custom-bot-without-proxy';
-
-  const fetchData = useCallback(async() => {
-    try {
-      await adminAppContainer.retrieveAppSettingsData();
-      const res = await appContainer.apiv3.get('/slack-integration/');
-      const {
-        slackSigningSecret, slackBotToken, slackSigningSecretEnvVars, slackBotTokenEnvVars,
-      } = res.data.slackBotSettingParams.customBotWithoutProxySettings;
-      setSlackSigningSecret(slackSigningSecret);
-      setSlackBotToken(slackBotToken);
-      setSlackSigningSecretEnv(slackSigningSecretEnvVars);
-      setSlackBotTokenEnv(slackBotTokenEnvVars);
-    }
-    catch (err) {
-      toastError(err);
-    }
-  }, [appContainer, adminAppContainer]);
-
-  useEffect(() => {
-    fetchData();
-  }, [fetchData]);
+  const currentBotType = 'customBotWithoutProxy';
 
 
   const updateSecretTokenHandler = async() => {
   const updateSecretTokenHandler = async() => {
     try {
     try {
@@ -56,10 +36,10 @@ const CustomBotWithoutProxySettingsAccordion = ({ appContainer, adminAppContaine
         slackBotToken,
         slackBotToken,
         currentBotType,
         currentBotType,
       });
       });
-      fetchData();
-      toastSuccess(t('toaster.update_successed', { target: t('slack_integration.custom_bot_without_proxy_settings') }));
+      toastSuccess(t('toaster.update_successed', { target: t('admin:slack_integration.custom_bot_without_proxy_settings') }));
     }
     }
     catch (err) {
     catch (err) {
+      setIsRegisterSlackCredentials(false);
       toastError(err);
       toastError(err);
     }
     }
   };
   };
@@ -76,12 +56,14 @@ const CustomBotWithoutProxySettingsAccordion = ({ appContainer, adminAppContaine
     setConnectionErrorCode(null);
     setConnectionErrorCode(null);
     setConnectionErrorMessage(null);
     setConnectionErrorMessage(null);
     try {
     try {
-      await appContainer.apiv3.post('slack-integration/notification-test-to-slack-work-space', {
+      await appContainer.apiv3.post('admin:slack-integration/notification-test-to-slack-work-space', {
         // TODO put proper request
         // TODO put proper request
-        channel: 'testchannel',
+        // channel: 'testchannel',
       });
       });
+      setIsSendTestMessage(true);
     }
     }
     catch (err) {
     catch (err) {
+      setIsSendTestMessage(false);
       setConnectionErrorCode(err[0].code);
       setConnectionErrorCode(err[0].code);
       setConnectionErrorMessage(err[0].message);
       setConnectionErrorMessage(err[0].message);
     }
     }
@@ -91,13 +73,13 @@ const CustomBotWithoutProxySettingsAccordion = ({ appContainer, adminAppContaine
     <div className="card border-0 rounded-lg shadow overflow-hidden">
     <div className="card border-0 rounded-lg shadow overflow-hidden">
       <Accordion
       <Accordion
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.CREATE_BOT)}
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.CREATE_BOT)}
-        title={<><span className="mr-2">①</span>{t('slack_integration.without_proxy.create_bot')}</>}
+        title={<><span className="mr-2">①</span>{t('admin:slack_integration.without_proxy.create_bot')}</>}
       >
       >
         <div className="row my-5">
         <div className="row my-5">
           <div className="mx-auto">
           <div className="mx-auto">
             <div>
             <div>
               <button type="button" className="btn btn-primary text-nowrap mx-1" onClick={() => window.open('https://api.slack.com/apps', '_blank')}>
               <button type="button" className="btn btn-primary text-nowrap mx-1" onClick={() => window.open('https://api.slack.com/apps', '_blank')}>
-                {t('slack_integration.without_proxy.create_bot')}
+                {t('admin:slack_integration.without_proxy.create_bot')}
                 <i className="fa fa-external-link ml-2" aria-hidden="true" />
                 <i className="fa fa-external-link ml-2" aria-hidden="true" />
               </button>
               </button>
             </div>
             </div>
@@ -105,7 +87,7 @@ const CustomBotWithoutProxySettingsAccordion = ({ appContainer, adminAppContaine
             <a href="#">
             <a href="#">
               <p className="text-center mt-1">
               <p className="text-center mt-1">
                 <small>
                 <small>
-                  {t('slack_integration.without_proxy.how_to_create_a_bot')}
+                  {t('admin:slack_integration.without_proxy.how_to_create_a_bot')}
                   <i className="fa fa-external-link ml-2" aria-hidden="true" />
                   <i className="fa fa-external-link ml-2" aria-hidden="true" />
                 </small>
                 </small>
               </p>
               </p>
@@ -115,25 +97,26 @@ const CustomBotWithoutProxySettingsAccordion = ({ appContainer, adminAppContaine
       </Accordion>
       </Accordion>
       <Accordion
       <Accordion
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.INSTALL_BOT)}
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.INSTALL_BOT)}
-        title={<><span className="mr-2">②</span>{t('slack_integration.without_proxy.install_bot_to_slack')}</>}
+        title={<><span className="mr-2">②</span>{t('admin:slack_integration.without_proxy.install_bot_to_slack')}</>}
       >
       >
         <div className="container w-75 py-5">
         <div className="container w-75 py-5">
-          <p>1. Install your app をクリックします。</p>
+          <p>1. {t('admin:slack_integration.without_proxy.select_install_your_app')}</p>
           <img src="/images/slack-integration/slack-bot-install-your-app-introduction.png" className="border border-light img-fluid mb-5" />
           <img src="/images/slack-integration/slack-bot-install-your-app-introduction.png" className="border border-light img-fluid mb-5" />
-          <p>2. Install to Workspace をクリックします。</p>
+          <p>2. {t('admin:slack_integration.without_proxy.select_install_to_workspace')}</p>
           <img src="/images/slack-integration/slack-bot-install-to-workspace.png" className="border border-light img-fluid mb-5" />
           <img src="/images/slack-integration/slack-bot-install-to-workspace.png" className="border border-light img-fluid mb-5" />
-          <p>3. 遷移先の画面にて、Allowをクリックします。</p>
+          <p>3. {t('admin:slack_integration.without_proxy.click_allow')}</p>
           <img src="/images/slack-integration/slack-bot-install-your-app-transition-destination.png" className="border border-light img-fluid mb-5" />
           <img src="/images/slack-integration/slack-bot-install-your-app-transition-destination.png" className="border border-light img-fluid mb-5" />
-          <p>4. Install your app の右側に 緑色のチェックがつけばワークスペースへのインストール完了です。</p>
+          <p>4. {t('admin:slack_integration.without_proxy.install_complete_if_checked')}</p>
           <img src="/images/slack-integration/slack-bot-install-your-app-complete.png" className="border border-light img-fluid mb-5" />
           <img src="/images/slack-integration/slack-bot-install-your-app-complete.png" className="border border-light img-fluid mb-5" />
-          <p>5. GROWI bot を使いたいチャンネルに @example を使用して招待します。</p>
+          <p>5. {t('admin:slack_integration.without_proxy.invite_bot_to_channel')}</p>
           <img src="/images/slack-integration/slack-bot-install-to-workspace-joined-bot.png" className="border border-light img-fluid mb-1" />
           <img src="/images/slack-integration/slack-bot-install-to-workspace-joined-bot.png" className="border border-light img-fluid mb-1" />
           <img src="/images/slack-integration/slack-bot-install-your-app-introduction-to-channel.png" className="border border-light img-fluid" />
           <img src="/images/slack-integration/slack-bot-install-your-app-introduction-to-channel.png" className="border border-light img-fluid" />
         </div>
         </div>
       </Accordion>
       </Accordion>
       <Accordion
       <Accordion
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.REGISTER_SLACK_CONFIGURATION)}
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.REGISTER_SLACK_CONFIGURATION)}
-        title={<><span className="mr-2">③</span>{t('slack_integration.without_proxy.register_secret_and_token')}</>}
+        // eslint-disable-next-line max-len
+        title={<><span className="mr-2">③</span>{t('admin:slack_integration.without_proxy.register_secret_and_token')}{isRegisterSlackCredentials && <i className="ml-3 text-success fa fa-check"></i>}</>}
       >
       >
         <CustomBotWithoutProxySecretTokenSection
         <CustomBotWithoutProxySecretTokenSection
           updateSecretTokenHandler={updateSecretTokenHandler}
           updateSecretTokenHandler={updateSecretTokenHandler}
@@ -147,14 +130,15 @@ const CustomBotWithoutProxySettingsAccordion = ({ appContainer, adminAppContaine
       </Accordion>
       </Accordion>
       <Accordion
       <Accordion
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.CONNECTION_TEST)}
         defaultIsActive={defaultOpenAccordionKeys.has(botInstallationStep.CONNECTION_TEST)}
-        title={<><span className="mr-2">④</span>{t('slack_integration.without_proxy.test_connection')}</>}
+        // eslint-disable-next-line max-len
+        title={<><span className="mr-2">④</span>{t('admin:slack_integration.without_proxy.test_connection')}{isSendTestMessage && <i className="ml-3 text-success fa fa-check"></i>}</>}
       >
       >
-        <p className="text-center m-4">以下のテストボタンを押して、Slack連携が完了しているかの確認をしましょう</p>
+        <p className="text-center m-4">{t('admin:slack_integration.without_proxy.test_connection_by_pressing_button')}</p>
         <div className="d-flex justify-content-center">
         <div className="d-flex justify-content-center">
           <button type="button" className="btn btn-info m-3 px-5 font-weight-bold" onClick={onTestConnectionHandler}>Test</button>
           <button type="button" className="btn btn-info m-3 px-5 font-weight-bold" onClick={onTestConnectionHandler}>Test</button>
         </div>
         </div>
         {connectionErrorMessage != null
         {connectionErrorMessage != null
-          && <p className="text-danger text-center m-4">エラーが発生しました。下記のログを確認してください。</p>
+          && <p className="text-danger text-center m-4">{t('admin:slack_integration.without_proxy.error_check_logs_below')}</p>
         }
         }
         <div className="row m-3 justify-content-center">
         <div className="row m-3 justify-content-center">
           <div className="col-sm-5 slack-connection-error-log">
           <div className="col-sm-5 slack-connection-error-log">
@@ -174,6 +158,16 @@ const CustomBotWithoutProxySettingsAccordionWrapper = withUnstatedContainers(Cus
 
 
 CustomBotWithoutProxySettingsAccordion.propTypes = {
 CustomBotWithoutProxySettingsAccordion.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+  slackSigningSecret: PropTypes.string,
+  slackSigningSecretEnv: PropTypes.string,
+  slackBotToken: PropTypes.string,
+  slackBotTokenEnv: PropTypes.string,
+  isRegisterSlackCredentials: PropTypes.bool,
+  isSendTestMessage: PropTypes.bool,
+  setSlackSigningSecret: PropTypes.string,
+  setSlackBotToken: PropTypes.string,
+  setIsSendTestMessage: PropTypes.func,
+  setIsRegisterSlackCredentials: PropTypes.func,
   adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
   adminAppContainer: PropTypes.instanceOf(AdminAppContainer).isRequired,
   activeStep: PropTypes.oneOf(Object.values(botInstallationStep)).isRequired,
   activeStep: PropTypes.oneOf(Object.values(botInstallationStep)).isRequired,
 };
 };

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

@@ -20,18 +20,40 @@ const SlackIntegration = (props) => {
   const [currentBotType, setCurrentBotType] = useState(null);
   const [currentBotType, setCurrentBotType] = useState(null);
   const [selectedBotType, setSelectedBotType] = useState(null);
   const [selectedBotType, setSelectedBotType] = useState(null);
   const [accessToken, setAccessToken] = useState('');
   const [accessToken, setAccessToken] = useState('');
+  const [slackSigningSecret, setSlackSigningSecret] = useState('');
+  const [slackBotToken, setSlackBotToken] = useState('');
+  const [slackSigningSecretEnv, setSlackSigningSecretEnv] = useState('');
+  const [slackBotTokenEnv, setSlackBotTokenEnv] = useState('');
+  const [isConnectedToSlack, setIsConnectedToSlack] = useState(null);
+  const [isRegisterSlackCredentials, setIsRegisterSlackCredentials] = useState(false);
+  const [isSendTestMessage, setIsSendTestMessage] = useState(false);
+
 
 
   const fetchData = useCallback(async() => {
   const fetchData = useCallback(async() => {
     try {
     try {
       const response = await appContainer.apiv3.get('slack-integration/');
       const response = await appContainer.apiv3.get('slack-integration/');
-      const { currentBotType, accessToken } = response.data.slackBotSettingParams;
+      const { currentBotType, customBotWithoutProxySettings, accessToken } = response.data.slackBotSettingParams;
+      const {
+        slackSigningSecret, slackBotToken, slackSigningSecretEnvVars, slackBotTokenEnvVars,
+      } = customBotWithoutProxySettings;
+
       setCurrentBotType(currentBotType);
       setCurrentBotType(currentBotType);
       setAccessToken(accessToken);
       setAccessToken(accessToken);
+      setSlackSigningSecret(slackSigningSecret);
+      setSlackBotToken(slackBotToken);
+      setSlackSigningSecretEnv(slackSigningSecretEnvVars);
+      setSlackBotTokenEnv(slackBotTokenEnvVars);
+      setIsConnectedToSlack(isConnectedToSlack);
+
+      if ((slackBotToken && slackSigningSecret) || (slackBotTokenEnv && slackSigningSecretEnv)) {
+        setIsRegisterSlackCredentials(true);
+      }
+
     }
     }
     catch (err) {
     catch (err) {
       toastError(err);
       toastError(err);
     }
     }
-  }, [appContainer.apiv3]);
+  }, [appContainer.apiv3, isConnectedToSlack, slackBotTokenEnv, slackSigningSecretEnv]);
 
 
   useEffect(() => {
   useEffect(() => {
     fetchData();
     fetchData();
@@ -45,6 +67,9 @@ const SlackIntegration = (props) => {
       setCurrentBotType(clickedBotType);
       setCurrentBotType(clickedBotType);
       return;
       return;
     }
     }
+    setIsRegisterSlackCredentials(false);
+    setSlackSigningSecret('');
+    setSlackBotToken('');
     setSelectedBotType(clickedBotType);
     setSelectedBotType(clickedBotType);
   };
   };
 
 
@@ -97,7 +122,20 @@ const SlackIntegration = (props) => {
       break;
       break;
     case 'customBotWithoutProxy':
     case 'customBotWithoutProxy':
       settingsComponent = (
       settingsComponent = (
-        <CustomBotWithoutProxySettings />
+        <CustomBotWithoutProxySettings
+          accessToken={accessToken}
+          isSendTestMessage={isSendTestMessage}
+          isRegisterSlackCredentials={isRegisterSlackCredentials}
+          isConnectedToSlack={isConnectedToSlack}
+          slackBotTokenEnv={slackBotTokenEnv}
+          slackBotToken={slackBotToken}
+          slackSigningSecretEnv={slackSigningSecretEnv}
+          slackSigningSecret={slackSigningSecret}
+          setSlackSigningSecret={setSlackSigningSecret}
+          setSlackBotToken={setSlackBotToken}
+          setIsSendTestMessage={setIsSendTestMessage}
+          setIsRegisterSlackCredentials={setIsRegisterSlackCredentials}
+        />
       );
       );
       break;
       break;
     case 'customBotWithProxy':
     case 'customBotWithProxy':