Yuki Takei 4 лет назад
Родитель
Сommit
f483ba7f74

+ 3 - 0
packages/app/src/client/services/AdminNotificationContainer.js

@@ -36,6 +36,9 @@ export default class AdminNotificationContainer extends Container {
     const { notificationParams } = response.data;
 
     this.setState({
+      isSlackbotConfigured: notificationParams.isSlackbotConfigured,
+      isSlackLegacyConfigured: notificationParams.isSlackLegacyConfigured,
+
       userNotifications: notificationParams.userNotifications,
       isNotificationForOwnerPageEnabled: notificationParams.isNotificationForOwnerPageEnabled,
       isNotificationForGroupPageEnabled: notificationParams.isNotificationForGroupPageEnabled,

+ 1 - 0
packages/app/src/client/services/AdminSlackIntegrationLegacyContainer.js

@@ -14,6 +14,7 @@ export default class AdminSlackIntegrationLegacyContainer extends Container {
     this.dummyWebhookUrlForError = 1;
 
     this.state = {
+      isSlackbotConfigured: false,
       retrieveError: null,
       selectSlackOption: 'Incoming Webhooks',
       webhookUrl: this.dummyWebhookUrl,

+ 87 - 1
packages/app/src/components/Admin/Notification/NotificationSetting.jsx

@@ -3,7 +3,10 @@ import React, {
 } from 'react';
 import PropTypes from 'prop-types';
 
-import { TabContent, TabPane } from 'reactstrap';
+import {
+  Card, CardBody, TabContent, TabPane,
+} from 'reactstrap';
+import { useTranslation } from 'react-i18next';
 import loggerFactory from '~/utils/logger';
 
 import { withUnstatedContainers } from '../../UnstatedUtils';
@@ -21,9 +24,70 @@ import GlobalNotification from './GlobalNotification';
 const logger = loggerFactory('growi:NotificationSetting');
 
 let retrieveErrors = null;
+
+
+const EnabledBadge = () => <span className="badge badge-success">Enabled</span>;
+const DisabledBadge = () => <span className="badge badge-secondary">Disabled</span>;
+
+const SkeltonListItem = () => (
+  <li className="list-group-item">
+    <h4 className="mb-2">
+      <span className="badge badge-secondary">――</span>
+      <span className="ml-2">...</span>
+    </h4>
+  </li>
+);
+
+// eslint-disable-next-line react/prop-types
+const SlackIntegrationListItem = ({ isSlackEnabled }) => {
+  const { t } = useTranslation();
+
+  return (
+    <li className="list-group-item">
+      <h4 className="mb-2">
+        { isSlackEnabled ? <EnabledBadge /> : <DisabledBadge /> }
+        <a href="/admin/slack-integration" className="ml-2">{t('slack_integration')}</a>
+      </h4>
+      { isSlackEnabled && (
+        <ul className="pl-4">
+          <li>
+            CAUTION: Currently, notifications that are configurable in this page
+            will notify only to the primary Slack Workspace.
+          </li>
+        </ul>
+      ) }
+    </li>
+  );
+};
+
+// eslint-disable-next-line react/prop-types
+const LegacySlackIntegrationListItem = ({ isSlackLegacyEnabled }) => {
+  const { t } = useTranslation();
+
+  return (
+    <li className="list-group-item">
+      <h4 className="mb-1">
+        { isSlackLegacyEnabled ? <EnabledBadge /> : <DisabledBadge /> }
+        <a href="/admin/slack-integration-legacy" className="ml-2">{t('legacy_slack_integration')}</a>
+      </h4>
+      { isSlackLegacyEnabled && (
+        <ul className="pl-4">
+          <li>
+            {/* eslint-disable-next-line react/no-danger */}
+            <span className="text-danger" dangerouslySetInnerHTML={{ __html: t('admin:slack_integration_legacy.alert_deplicated') }}></span>
+          </li>
+        </ul>
+      ) }
+    </li>
+  );
+};
+
 function NotificationSetting(props) {
   const { adminNotificationContainer } = props;
 
+  const { t } = useTranslation();
+
+  const [isMounted, setMounted] = useState(false);
   const [activeTab, setActiveTab] = useState('user_trigger_notification');
   const [activeComponents, setActiveComponents] = useState(new Set(['user_trigger_notification']));
 
@@ -42,6 +106,9 @@ function NotificationSetting(props) {
       logger.error(errs);
       retrieveErrors = errs;
     }
+    finally {
+      setMounted(true);
+    }
   }, [adminNotificationContainer]);
 
   useEffect(() => {
@@ -63,8 +130,27 @@ function NotificationSetting(props) {
     };
   }, []);
 
+  const { isSlackbotConfigured, isSlackLegacyConfigured } = adminNotificationContainer.state;
+  const isSlackEnabled = isSlackbotConfigured;
+  const isSlackLegacyEnabled = !isSlackbotConfigured && isSlackLegacyConfigured;
+
   return (
     <>
+      <h2 className="admin-setting-header">Slack Integration Status</h2>
+      <ul className="list-group">
+        { !isMounted && <SkeltonListItem />}
+        { isMounted && (
+          <>
+            <SlackIntegrationListItem isSlackEnabled />
+            {/* Legacy Slack Integration become visible only when new Slack Integration is disabled */}
+            { !isSlackEnabled && <LegacySlackIntegrationListItem isSlackLegacyEnabled /> }
+          </>
+        ) }
+      </ul>
+
+
+      <h2 className="admin-setting-header mt-5">{t('Notification Settings')}</h2>
+
       <CustomNavTab activeTab={activeTab} navTabMapping={navTabMapping} onNavSelected={switchActiveTab} hideBorderBottom />
 
       <TabContent activeTab={activeTab} className="p-5">

+ 4 - 0
packages/app/src/server/routes/apiv3/notification-setting.js

@@ -118,6 +118,10 @@ module.exports = (crowi) => {
   router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
 
     const notificationParams = {
+      // status of slack intagration
+      isSlackbotConfigured: crowi.slackIntegrationService.isSlackbotConfigured,
+      isSlackLegacyConfigured: crowi.slackIntegrationService.isSlackLegacyConfigured,
+
       userNotifications: await UpdatePost.findAll(),
       isNotificationForOwnerPageEnabled: await crowi.configManager.getConfig('notification', 'notification:owner-page:isEnabled'),
       isNotificationForGroupPageEnabled: await crowi.configManager.getConfig('notification', 'notification:group-page:isEnabled'),