ソースを参照

Merge branch 'feat/growi-bot' into imprv/gw5855-growi-url-in-accordion

kaori 4 年 前
コミット
2e35e8464c

+ 8 - 0
packages/slackbot-proxy/src/Server.ts

@@ -75,6 +75,14 @@ export class Server {
   @Inject()
   @Inject()
   injector: InjectorService;
   injector: InjectorService;
 
 
+  $onInit(): Promise<any> | void {
+    const serverUri = process.env.SERVER_URI;
+
+    if (serverUri === undefined) {
+      throw new Error('The environment variable \'SERVER_URI\' must be defined.');
+    }
+  }
+
   $beforeRoutesInit(): void {
   $beforeRoutesInit(): void {
     this.app
     this.app
       .use(cookieParser())
       .use(cookieParser())

+ 1 - 1
packages/slackbot-proxy/src/controllers/slack.ts

@@ -155,7 +155,7 @@ export class SlackCtrl {
     // register
     // register
     if (type === 'view_submission' && payload.response_urls[0].action_id === 'submit_growi_url_and_access_tokens') {
     if (type === 'view_submission' && payload.response_urls[0].action_id === 'submit_growi_url_and_access_tokens') {
       await this.registerService.upsertOrderRecord(this.orderRepository, installation, payload);
       await this.registerService.upsertOrderRecord(this.orderRepository, installation, payload);
-      await this.registerService.showProxyUrl(authorizeResult, payload);
+      await this.registerService.notifyServerUriToSlack(authorizeResult, payload);
       return;
       return;
     }
     }
 
 

+ 4 - 9
packages/slackbot-proxy/src/services/RegisterService.ts

@@ -6,7 +6,6 @@ import { GrowiCommandProcessor } from '~/interfaces/growi-command-processor';
 import { OrderRepository } from '~/repositories/order';
 import { OrderRepository } from '~/repositories/order';
 import { Installation } from '~/entities/installation';
 import { Installation } from '~/entities/installation';
 
 
-
 const isProduction = process.env.NODE_ENV === 'production';
 const isProduction = process.env.NODE_ENV === 'production';
 
 
 @Service()
 @Service()
@@ -79,19 +78,15 @@ export class RegisterService implements GrowiCommandProcessor {
     }
     }
   }
   }
 
 
-  async showProxyUrl(
+  async notifyServerUriToSlack(
       // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
       // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
       authorizeResult:AuthorizeResult, payload: any,
       authorizeResult:AuthorizeResult, payload: any,
   ): Promise<void> {
   ): Promise<void> {
 
 
-    // TODO: implement for when proxy URL is undefined by GW-5834
-    let proxyURL;
-    if (process.env.PROXY_URL != null) {
-      proxyURL = process.env.PROXY_URL;
-    }
-
     const { botToken } = authorizeResult;
     const { botToken } = authorizeResult;
 
 
+    const serverUri = process.env.SERVER_URI;
+
     const client = new WebClient(botToken, { logLevel: isProduction ? LogLevel.DEBUG : LogLevel.INFO });
     const client = new WebClient(botToken, { logLevel: isProduction ? LogLevel.DEBUG : LogLevel.INFO });
 
 
     await client.chat.postEphemeral({
     await client.chat.postEphemeral({
@@ -102,7 +97,7 @@ export class RegisterService implements GrowiCommandProcessor {
       text: 'Proxy URL',
       text: 'Proxy URL',
       blocks: [
       blocks: [
         generateMarkdownSectionBlock('Please enter and update the following Proxy URL to slack bot setting form in your GROWI'),
         generateMarkdownSectionBlock('Please enter and update the following Proxy URL to slack bot setting form in your GROWI'),
-        generateMarkdownSectionBlock(`Proxy URL: ${proxyURL}`),
+        generateMarkdownSectionBlock(`Proxy URL: ${serverUri}`),
       ],
       ],
     });
     });
     return;
     return;

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

@@ -296,6 +296,13 @@
       "how_to_install": "How to install",
       "how_to_install": "How to install",
       "install_bot_to_slack": "Install Bot To Slack",
       "install_bot_to_slack": "Install Bot To Slack",
       "install_now": "Install now",
       "install_now": "Install now",
+      "generate_access_token": "Generate Access Token",
+      "register_for_growi_official_bot_proxy_service": "Register for GROWI Official Bot Proxy Service",
+      "enter_growi_register_on_slack": "Enter `/growi register` on slack",
+      "paste_growi_url": "Enter `http://localhost:3000` for <b>GROWI URL</b>",
+      "enter_access_token_for_growi_and_proxy": "Enter <b>Access Token for GROWI</b> and <b>Access Token for Proxy</b>",
+      "set_proxy_url_on_growi": "Set Proxy URL on GROWI",
+      "enter_proxy_url_and_update": "Enter <b>Proxy URL</b> shown on Slack and click Update",
       "select_install_your_app": "Select \"Install your app\".",
       "select_install_your_app": "Select \"Install your app\".",
       "select_install_to_workspace": "Select \"Install to Workspace\".",
       "select_install_to_workspace": "Select \"Install to Workspace\".",
       "register_official_bot_proxy_service": "Issue Access Token / Register GROWI Official Bot Proxy Service",
       "register_official_bot_proxy_service": "Issue Access Token / Register GROWI Official Bot Proxy Service",

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

@@ -293,6 +293,13 @@
       "how_to_install": "インストール方法はこちら",
       "how_to_install": "インストール方法はこちら",
       "install_bot_to_slack": "Bot を Slack にインストールする",
       "install_bot_to_slack": "Bot を Slack にインストールする",
       "install_now": "今すぐインストール",
       "install_now": "今すぐインストール",
+      "generate_access_token": "Access Tokenの発行",
+      "register_for_growi_official_bot_proxy_service": "GROWI Official Bot Proxy サービスへの登録",
+      "enter_growi_register_on_slack": "Slack上で `/growi register` と打つ",
+      "paste_growi_url": "<b>GROWI URL</b>には`http://localhost:3000`を貼り付ける",
+      "enter_access_token_for_growi_and_proxy": "上記で発行した<b>Access Token for GROWI</b> と <b>Access Token for Proxy</b>を入れる",
+      "set_proxy_url_on_growi": "ProxyのURLをGROWIに登録する",
+      "enter_proxy_url_and_update": "Slack上に通知された<b>Proxy URL</b>を入力し、更新してください。",
       "select_install_your_app": "Install your app をクリックします。",
       "select_install_your_app": "Install your app をクリックします。",
       "select_install_to_workspace": "Install to Workspace をクリックします。",
       "select_install_to_workspace": "Install to Workspace をクリックします。",
       "register_official_bot_proxy_service": "アクセストークンの発行 / GROWI Official Bot Proxy サービスへの登録",
       "register_official_bot_proxy_service": "アクセストークンの発行 / GROWI Official Bot Proxy サービスへの登録",

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

@@ -303,6 +303,13 @@
       "how_to_install": "点击这里查看安装说明",
       "how_to_install": "点击这里查看安装说明",
       "install_bot_to_slack": "将 Bot 安装到 Slack",
       "install_bot_to_slack": "将 Bot 安装到 Slack",
       "install_now": "现在安装",
       "install_now": "现在安装",
+      "generate_access_token": "生成Access Token",
+      "register_for_growi_official_bot_proxy_service": "注册 GROWI Official Bot Proxy Service",
+      "enter_growi_register_on_slack": "在Slack中,输入`/growi register`。",
+      "paste_growi_url": "将`http://localhost:3000`粘贴到 <b>GROWI URL</b> 网址中",
+      "enter_access_token_for_growi_and_proxy": "插入上面发出的 <b>Access Token for GROWI</b> 和 <b>Access Token for Proxy</b>。",
+      "set_proxy_url_on_growi": "向GROWI注册Proxy的URL",
+      "enter_proxy_url_and_update": "按照Slack上的通知输入并更新你的 <b>Proxy URL</b>。",
       "select_install_your_app": "选择 \"Install your app\"。",
       "select_install_your_app": "选择 \"Install your app\"。",
       "select_install_to_workspace": "选择 \"Install to Workspace\"。",
       "select_install_to_workspace": "选择 \"Install to Workspace\"。",
       "register_official_bot_proxy_service": "发行访问令牌 / 注册 GROWI 官方 Bot 代理服务",
       "register_official_bot_proxy_service": "发行访问令牌 / 注册 GROWI 官方 Bot 代理服务",

+ 162 - 5
src/client/js/components/Admin/SlackIntegration/CustomBotWithProxySettingsAccordion.jsx

@@ -1,9 +1,38 @@
-import React from 'react';
+import React, { useState } from 'react';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
+import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 import Accordion from '../Common/Accordion';
 import Accordion from '../Common/Accordion';
 
 
 const CustomBotWithProxySettingsAccordion = () => {
 const CustomBotWithProxySettingsAccordion = () => {
+  const [testChannel, setTestChannel] = useState('');
+  /* eslint-disable no-unused-vars */
+  // TODO: Add connection Logs
+  const [connectionErrorCode, setConnectionErrorCode] = useState(null);
+  const [connectionErrorMessage, setConnectionErrorMessage] = useState(null);
+  const [connectionSuccessMessage, setConnectionSuccessMessage] = useState(null);
+
   const { t } = useTranslation();
   const { t } = useTranslation();
+
+  // TODO: Handle test button
+  const submitForm = (e) => {
+    e.preventDefault();
+    // eslint-disable-next-line no-console
+    console.log('Form Submitted');
+  };
+
+  const inputTestChannelHandler = (channel) => {
+    setTestChannel(channel);
+  };
+
+  // TODO: Show test logs
+  let value = '';
+  if (connectionErrorMessage != null) {
+    value = [connectionErrorCode, connectionErrorMessage];
+  }
+  if (connectionSuccessMessage != null) {
+    value = connectionSuccessMessage;
+  }
+
   return (
   return (
     <div className="card border-0 rounded-lg shadow overflow-hidden">
     <div className="card border-0 rounded-lg shadow overflow-hidden">
       <Accordion
       <Accordion
@@ -46,14 +75,142 @@ const CustomBotWithProxySettingsAccordion = () => {
         </div>
         </div>
       </Accordion>
       </Accordion>
       <Accordion
       <Accordion
-        title={<><span className="mr-2">③</span>Third Accordion</>}
+        title={(
+          <>
+            <span className="mr-2">③</span>
+            {t('admin:slack_integration.accordion.generate_access_token')}
+            {' / '}
+            {t('admin:slack_integration.accordion.register_for_growi_official_bot_proxy_service')}
+          </>
+        )}
+      >
+        <div className="py-4 px-5">
+          <p className="font-weight-bold">1. {t('admin:slack_integration.accordion.generate_access_token')}</p>
+          <div className="form-group row">
+            <label className="text-left text-md-right col-md-3 col-form-label">Access Token for GROWI</label>
+            <div className="col-md-6">
+              <input
+                className="form-control"
+                type="text"
+              />
+            </div>
+          </div>
+          <div className="form-group row">
+            <label className="text-left text-md-right col-md-3 col-form-label">Access Token for Proxy</label>
+            <div className="col-md-6">
+              <input
+                className="form-control"
+                type="text"
+              />
+            </div>
+          </div>
+
+          <div className="row my-3">
+            <div className="mx-auto">
+              <button type="button" className="btn btn-outline-secondary mx-2">{ t('admin:slack_integration.access_token_settings.discard') }</button>
+              <button type="button" className="btn btn-primary mx-2">{ t('admin:slack_integration.access_token_settings.generate') }</button>
+            </div>
+          </div>
+          <p className="font-weight-bold">2. {t('admin:slack_integration.accordion.register_for_growi_official_bot_proxy_service')}</p>
+          <div className="d-flex flex-column align-items-center">
+            <ol className="p-0">
+              <li><p className="ml-2">{t('admin:slack_integration.accordion.enter_growi_register_on_slack')}</p></li>
+              <li>
+                <p
+                  className="ml-2"
+                  // TODO: Add dynamic link
+                  // TODO: Copy to clipboard on click
+                  // TODO: Add logo
+                  // eslint-disable-next-line react/no-danger
+                  dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.accordion.paste_growi_url') }}
+                />
+              </li>
+              <li>
+                <p
+                  className="ml-2"
+                  // eslint-disable-next-line react/no-danger
+                  dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.accordion.enter_access_token_for_growi_and_proxy') }}
+                />
+              </li>
+            </ol>
+            {/* TODO: Insert photo */}
+            <div className="rounded border w-50 d-flex justify-content-center align-items-center" style={{ height: '15rem' }}>
+              <h1 className="text-muted">参考画像</h1>
+            </div>
+          </div>
+        </div>
+      </Accordion>
+      <Accordion
+        title={<><span className="mr-2">④</span>{t('admin:slack_integration.accordion.set_proxy_url_on_growi')}</>}
       >
       >
-        3
+        <div className="p-4">
+          <p
+            className="text-center"
+            // eslint-disable-next-line react/no-danger
+            dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.accordion.enter_proxy_url_and_update') }}
+          />
+          <div className="form-group row my-4">
+            <label className="text-left text-md-right col-md-3 col-form-label">Proxy URL</label>
+            <div className="col-md-6">
+              <input
+                className="form-control"
+                type="text"
+              />
+            </div>
+          </div>
+          <AdminUpdateButtonRow
+            disabled={false}
+            // TODO: Add Proxy URL submit logic
+            // eslint-disable-next-line no-console
+            onClick={() => console.log('Update')}
+          />
+        </div>
       </Accordion>
       </Accordion>
       <Accordion
       <Accordion
-        title={<><span className="mr-2">④</span>Fourth Accordion</>}
+        title={<><span className="mr-2">⑤</span>{t('admin:slack_integration.accordion.test_connection')}</>}
       >
       >
-        4
+        {/* TODO: Responsive */}
+        <p className="text-center m-4">{t('admin:slack_integration.accordion.test_connection_by_pressing_button')}</p>
+        <div className="d-flex justify-content-center">
+          <form className="form-row align-items-center w-25" onSubmit={e => submitForm(e)}>
+            <div className="col-8 input-group-prepend">
+              <span className="input-group-text" id="slack-channel-addon"><i className="fa fa-hashtag" /></span>
+              <input
+                className="form-control w-100"
+                type="text"
+                value={testChannel}
+                placeholder="Slack Channel"
+                // TODO: Handle test button
+                onChange={e => inputTestChannelHandler(e.target.value)}
+              />
+            </div>
+            <div className="col-4">
+              <button
+                type="submit"
+                className="btn btn-info mx-3 font-weight-bold"
+                disabled={testChannel.trim() === ''}
+              >Test
+              </button>
+            </div>
+          </form>
+        </div>
+        {connectionErrorMessage != null
+          && <p className="text-danger text-center my-4">{t('admin:slack_integration.accordion.error_check_logs_below')}</p>}
+        {connectionSuccessMessage != null
+          && <p className="text-info text-center my-4">{t('admin:slack_integration.accordion.send_message_to_slack_work_space')}</p>}
+        <form>
+          <div className="row my-3 justify-content-center">
+            <div className="form-group slack-connection-log w-25">
+              <label className="mb-1"><p className="border-info slack-connection-log-title pl-2">Logs</p></label>
+              <textarea
+                className="form-control card border-info slack-connection-log-body rounded-lg"
+                // TODO: Show test logs
+                value={value}
+                readOnly
+              />
+            </div>
+          </div>
+        </form>
       </Accordion>
       </Accordion>
     </div>
     </div>
   );
   );

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

@@ -96,6 +96,7 @@ const OfficialBotSettingsAccordion = () => {
           <AdminUpdateButtonRow
           <AdminUpdateButtonRow
             disabled={false}
             disabled={false}
             // TODO: Add Proxy URL submit logic
             // TODO: Add Proxy URL submit logic
+            // eslint-disable-next-line no-console
             onClick={() => console.log('Update')}
             onClick={() => console.log('Update')}
           />
           />
         </div>
         </div>