|
@@ -1,12 +1,16 @@
|
|
|
|
|
+/* eslint-disable react/prop-types */
|
|
|
import React, { useState } 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 { CopyToClipboard } from 'react-copy-to-clipboard';
|
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
|
|
|
|
+import loggerFactory from '@alias/logger';
|
|
|
|
|
+
|
|
|
import { withUnstatedContainers } from '../../UnstatedUtils';
|
|
import { withUnstatedContainers } from '../../UnstatedUtils';
|
|
|
import { toastSuccess } from '../../../util/apiNotification';
|
|
import { toastSuccess } from '../../../util/apiNotification';
|
|
|
import AppContainer from '../../../services/AppContainer';
|
|
import AppContainer from '../../../services/AppContainer';
|
|
|
import Accordion from '../Common/Accordion';
|
|
import Accordion from '../Common/Accordion';
|
|
|
|
|
|
|
|
|
|
+const logger = loggerFactory('growi:SlackIntegration:WithProxyAccordionsWrapper');
|
|
|
|
|
|
|
|
const BotCreateProcess = () => {
|
|
const BotCreateProcess = () => {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
@@ -73,15 +77,9 @@ const RegisteringProxyUrlProcess = () => {
|
|
|
const GeneratingTokensAndRegisteringProxyServiceProcess = withUnstatedContainers((props) => {
|
|
const GeneratingTokensAndRegisteringProxyServiceProcess = withUnstatedContainers((props) => {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
|
|
|
|
|
- const generateTokenHandler = () => {
|
|
|
|
|
- if (props.generateTokenHandler != null) {
|
|
|
|
|
- props.generateTokenHandler();
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- const discardTokenHandler = () => {
|
|
|
|
|
- if (props.discardTokenHandler != null) {
|
|
|
|
|
- props.discardTokenHandler();
|
|
|
|
|
|
|
+ const onClickGenerateTokenBtn = () => {
|
|
|
|
|
+ if (props.onClickGenerateTokenBtn != null) {
|
|
|
|
|
+ props.onClickGenerateTokenBtn();
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -116,23 +114,13 @@ const GeneratingTokensAndRegisteringProxyServiceProcess = withUnstatedContainers
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div className="row my-3">
|
|
<div className="row my-3">
|
|
|
- <div className="mx-auto">
|
|
|
|
|
- <button
|
|
|
|
|
- type="button"
|
|
|
|
|
- className="btn btn-outline-secondary mx-2"
|
|
|
|
|
- onClick={discardTokenHandler}
|
|
|
|
|
- disabled={props.tokenGtoP == null || props.tokenPtoG == null}
|
|
|
|
|
- >
|
|
|
|
|
- { t('admin:slack_integration.access_token_settings.discard') }
|
|
|
|
|
- </button>
|
|
|
|
|
- <button
|
|
|
|
|
- type="button"
|
|
|
|
|
- className="btn btn-primary mx-2"
|
|
|
|
|
- onClick={generateTokenHandler}
|
|
|
|
|
- >
|
|
|
|
|
- { t('admin:slack_integration.access_token_settings.generate') }
|
|
|
|
|
- </button>
|
|
|
|
|
- </div>
|
|
|
|
|
|
|
+ <button
|
|
|
|
|
+ type="button"
|
|
|
|
|
+ className="btn btn-primary mx-auto"
|
|
|
|
|
+ onClick={onClickGenerateTokenBtn}
|
|
|
|
|
+ >
|
|
|
|
|
+ { t('admin:slack_integration.access_token_settings.regenerate') }
|
|
|
|
|
+ </button>
|
|
|
</div>
|
|
</div>
|
|
|
<p className="font-weight-bold">2. {t('admin:slack_integration.accordion.register_for_growi_official_bot_proxy_service')}</p>
|
|
<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">
|
|
<div className="d-flex flex-column align-items-center">
|
|
@@ -179,34 +167,27 @@ const GeneratingTokensAndRegisteringProxyServiceProcess = withUnstatedContainers
|
|
|
);
|
|
);
|
|
|
}, [AppContainer]);
|
|
}, [AppContainer]);
|
|
|
|
|
|
|
|
-const TestProcess = () => {
|
|
|
|
|
|
|
+const TestProcess = ({ apiv3Post, slackAppIntegrationId }) => {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
const [testChannel, setTestChannel] = useState('');
|
|
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 [connectionError, setConnectionError] = useState(null);
|
|
|
|
|
|
|
|
- // TODO: Show test logs
|
|
|
|
|
let value = '';
|
|
let value = '';
|
|
|
- if (connectionErrorMessage != null) {
|
|
|
|
|
- value = [connectionErrorCode, connectionErrorMessage];
|
|
|
|
|
- }
|
|
|
|
|
- if (connectionSuccessMessage != null) {
|
|
|
|
|
- value = connectionSuccessMessage;
|
|
|
|
|
|
|
+ if (connectionError != null) {
|
|
|
|
|
+ value = [connectionError.code, connectionError.message];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
- // TODO: Handle test button
|
|
|
|
|
- const submitForm = (e) => {
|
|
|
|
|
|
|
+ const submitForm = async(e) => {
|
|
|
e.preventDefault();
|
|
e.preventDefault();
|
|
|
- // eslint-disable-next-line no-console
|
|
|
|
|
- console.log('Form Submitted');
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ setConnectionError(null);
|
|
|
|
|
|
|
|
- const inputTestChannelHandler = (channel) => {
|
|
|
|
|
- setTestChannel(channel);
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ await apiv3Post('/slack-integration-settings/with-proxy/relation-test', { slackAppIntegrationId, channel: testChannel });
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (error) {
|
|
|
|
|
+ setConnectionError(error[0]);
|
|
|
|
|
+ logger.error(error);
|
|
|
|
|
+ }
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
@@ -223,22 +204,22 @@ const TestProcess = () => {
|
|
|
type="text"
|
|
type="text"
|
|
|
value={testChannel}
|
|
value={testChannel}
|
|
|
placeholder="Slack Channel"
|
|
placeholder="Slack Channel"
|
|
|
- // TODO: Handle test button
|
|
|
|
|
- onChange={e => inputTestChannelHandler(e.target.value)}
|
|
|
|
|
|
|
+ onChange={e => setTestChannel(e.target.value)}
|
|
|
/>
|
|
/>
|
|
|
</div>
|
|
</div>
|
|
|
<button
|
|
<button
|
|
|
type="submit"
|
|
type="submit"
|
|
|
className="btn btn-info mx-3 font-weight-bold"
|
|
className="btn btn-info mx-3 font-weight-bold"
|
|
|
disabled={testChannel.trim() === ''}
|
|
disabled={testChannel.trim() === ''}
|
|
|
- >Test
|
|
|
|
|
|
|
+ >
|
|
|
|
|
+ Test
|
|
|
</button>
|
|
</button>
|
|
|
</form>
|
|
</form>
|
|
|
</div>
|
|
</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>}
|
|
|
|
|
|
|
+ {connectionError == null
|
|
|
|
|
+ ? <p className="text-info text-center my-4">{t('admin:slack_integration.accordion.send_message_to_slack_work_space')}</p>
|
|
|
|
|
+ : <p className="text-danger text-center my-4">{t('admin:slack_integration.accordion.error_check_logs_below')}</p>
|
|
|
|
|
+ }
|
|
|
<form>
|
|
<form>
|
|
|
<div className="row my-3 justify-content-center">
|
|
<div className="row my-3 justify-content-center">
|
|
|
<div className="form-group slack-connection-log col-md-4">
|
|
<div className="form-group slack-connection-log col-md-4">
|
|
@@ -246,7 +227,6 @@ const TestProcess = () => {
|
|
|
<textarea
|
|
<textarea
|
|
|
className="form-control card border-info slack-connection-log-body rounded-lg"
|
|
className="form-control card border-info slack-connection-log-body rounded-lg"
|
|
|
rows="5"
|
|
rows="5"
|
|
|
- // TODO: Show test logs
|
|
|
|
|
value={value}
|
|
value={value}
|
|
|
readOnly
|
|
readOnly
|
|
|
/>
|
|
/>
|
|
@@ -270,8 +250,7 @@ const WithProxyAccordions = (props) => {
|
|
|
title: 'register_for_growi_official_bot_proxy_service',
|
|
title: 'register_for_growi_official_bot_proxy_service',
|
|
|
content: <GeneratingTokensAndRegisteringProxyServiceProcess
|
|
content: <GeneratingTokensAndRegisteringProxyServiceProcess
|
|
|
growiUrl={props.appContainer.config.crowi.url}
|
|
growiUrl={props.appContainer.config.crowi.url}
|
|
|
- discardTokenHandler={props.discardTokenHandler}
|
|
|
|
|
- generateTokenHandler={props.generateTokenHandler}
|
|
|
|
|
|
|
+ onClickGenerateTokenBtn={props.onClickGenerateTokenBtn}
|
|
|
tokenPtoG={props.tokenPtoG}
|
|
tokenPtoG={props.tokenPtoG}
|
|
|
tokenGtoP={props.tokenGtoP}
|
|
tokenGtoP={props.tokenGtoP}
|
|
|
/>,
|
|
/>,
|
|
@@ -299,8 +278,7 @@ const WithProxyAccordions = (props) => {
|
|
|
title: 'register_for_growi_official_bot_proxy_service',
|
|
title: 'register_for_growi_official_bot_proxy_service',
|
|
|
content: <GeneratingTokensAndRegisteringProxyServiceProcess
|
|
content: <GeneratingTokensAndRegisteringProxyServiceProcess
|
|
|
growiUrl={props.appContainer.config.crowi.url}
|
|
growiUrl={props.appContainer.config.crowi.url}
|
|
|
- discardTokenHandler={props.discardTokenHandler}
|
|
|
|
|
- generateTokenHandler={props.generateTokenHandler}
|
|
|
|
|
|
|
+ onClickGenerateTokenBtn={props.onClickGenerateTokenBtn}
|
|
|
tokenPtoG={props.tokenPtoG}
|
|
tokenPtoG={props.tokenPtoG}
|
|
|
tokenGtoP={props.tokenGtoP}
|
|
tokenGtoP={props.tokenGtoP}
|
|
|
/>,
|
|
/>,
|
|
@@ -311,7 +289,7 @@ const WithProxyAccordions = (props) => {
|
|
|
},
|
|
},
|
|
|
'⑤': {
|
|
'⑤': {
|
|
|
title: 'test_connection',
|
|
title: 'test_connection',
|
|
|
- content: <TestProcess />,
|
|
|
|
|
|
|
+ content: <TestProcess apiv3Post={props.appContainer.apiv3.post} slackAppIntegrationId={props.slackAppIntegrationId} />,
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -322,7 +300,6 @@ const WithProxyAccordions = (props) => {
|
|
|
className="card border-0 rounded-lg shadow overflow-hidden"
|
|
className="card border-0 rounded-lg shadow overflow-hidden"
|
|
|
>
|
|
>
|
|
|
{Object.entries(integrationProcedureMapping).map(([key, value]) => {
|
|
{Object.entries(integrationProcedureMapping).map(([key, value]) => {
|
|
|
-
|
|
|
|
|
return (
|
|
return (
|
|
|
<Accordion
|
|
<Accordion
|
|
|
title={<><span className="mr-2">{key}</span>{t(`admin:slack_integration.accordion.${value.title}`)}</>}
|
|
title={<><span className="mr-2">{key}</span>{t(`admin:slack_integration.accordion.${value.title}`)}</>}
|
|
@@ -340,14 +317,15 @@ const WithProxyAccordions = (props) => {
|
|
|
/**
|
|
/**
|
|
|
* Wrapper component for using unstated
|
|
* Wrapper component for using unstated
|
|
|
*/
|
|
*/
|
|
|
-const OfficialBotSettingsAccordionsWrapper = withUnstatedContainers(WithProxyAccordions, [AppContainer]);
|
|
|
|
|
|
|
+const WithProxyAccordionsWrapper = withUnstatedContainers(WithProxyAccordions, [AppContainer]);
|
|
|
WithProxyAccordions.propTypes = {
|
|
WithProxyAccordions.propTypes = {
|
|
|
appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
appContainer: PropTypes.instanceOf(AppContainer).isRequired,
|
|
|
botType: PropTypes.string.isRequired,
|
|
botType: PropTypes.string.isRequired,
|
|
|
- discardTokenHandler: PropTypes.func,
|
|
|
|
|
- generateTokenHandler: PropTypes.func,
|
|
|
|
|
|
|
+
|
|
|
|
|
+ slackAppIntegrationId: PropTypes.string.isRequired,
|
|
|
|
|
+ onClickGenerateTokenBtn: PropTypes.func,
|
|
|
tokenPtoG: PropTypes.string,
|
|
tokenPtoG: PropTypes.string,
|
|
|
tokenGtoP: PropTypes.string,
|
|
tokenGtoP: PropTypes.string,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
-export default OfficialBotSettingsAccordionsWrapper;
|
|
|
|
|
|
|
+export default WithProxyAccordionsWrapper;
|