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

Revert "fix: Styling error in the Slack Integration"

Yuki Takei 2 лет назад
Родитель
Сommit
cc5412f6e8
21 измененных файлов с 237 добавлено и 237 удалено
  1. 6 0
      apps/app/_obsolete/src/styles/theme/apply-colors.scss
  2. 1 0
      apps/app/next-env.d.ts
  3. 24 40
      apps/app/src/components/Admin/SlackIntegration/BotTypeCard.jsx
  4. 21 17
      apps/app/src/components/Admin/SlackIntegration/Bridge.jsx
  5. 57 0
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithProxyConnectionStatus.jsx
  6. 0 59
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithProxyConnectionStatus.tsx
  7. 2 2
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithProxySettings.jsx
  8. 57 0
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxyConnectionStatus.jsx
  9. 0 57
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxyConnectionStatus.tsx
  10. 1 1
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettings.jsx
  11. 1 1
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx
  12. 19 21
      apps/app/src/components/Admin/SlackIntegration/DeleteSlackBotSettingsModal.jsx
  13. 2 2
      apps/app/src/components/Admin/SlackIntegration/OfficialBotSettings.jsx
  14. 2 1
      apps/app/src/components/Admin/SlackIntegration/SlackAppIntegrationControl.tsx
  15. 12 12
      apps/app/src/components/Admin/SlackIntegration/SlackIntegration.jsx
  16. 1 1
      apps/app/src/components/Admin/SlackIntegration/WithProxyAccordions.jsx
  17. 0 4
      apps/app/src/components/Admin/SlackIntegration/slack-integration-util.ts
  18. 20 0
      apps/app/src/components/Admin/SlackIntegration/slak-integration-util.js
  19. 7 13
      apps/app/src/components/Layout/Admin.module.scss
  20. 4 5
      apps/app/src/pages/admin/slack-integration.page.tsx
  21. 0 1
      packages/slack/src/interfaces/index.ts

+ 6 - 0
apps/app/_obsolete/src/styles/theme/apply-colors.scss

@@ -402,6 +402,12 @@ ul.pagination {
   box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
 }
 
+.admin-bot-card {
+  .grw-botcard-title-active {
+    color: $gray-200;
+  }
+}
+
 /*
  * Form Slider
  */

+ 1 - 0
apps/app/next-env.d.ts

@@ -1,5 +1,6 @@
 /// <reference types="next" />
 /// <reference types="next/image-types/global" />
+/// <reference types="next/navigation-types/compat/navigation" />
 
 // NOTE: This file should not be edited
 // see https://nextjs.org/docs/basic-features/typescript for more information.

+ 24 - 40
apps/app/src/components/Admin/SlackIntegration/BotTypeCard.tsx → apps/app/src/components/Admin/SlackIntegration/BotTypeCard.jsx

@@ -2,7 +2,7 @@ import React from 'react';
 
 import { SlackbotType } from '@growi/slack';
 import { useTranslation } from 'next-i18next';
-import Image from 'next/image';
+import PropTypes from 'prop-types';
 
 const botDetails = {
   officialBot: {
@@ -30,33 +30,25 @@ const botDetails = {
   },
 };
 
-type BotTypeCardProps = {
-  isActive: boolean,
-  botType: string,
-  onBotTypeSelectHandler: (botType: SlackbotType) => void,
-};
-
-export const BotTypeCard = (props: BotTypeCardProps): JSX.Element => {
+const BotTypeCard = (props) => {
   const { t } = useTranslation();
 
-  const { isActive, botType, onBotTypeSelectHandler } = props;
-
-  const isBotTypeOfficial = botType === SlackbotType.OFFICIAL;
+  const isBotTypeOfficial = props.botType === SlackbotType.OFFICIAL;
 
   return (
     <div
-      className={`card admin-bot-card rounded border-radius-sm shadow ${isActive ? 'border-primary' : ''}`}
-      onClick={() => onBotTypeSelectHandler(botDetails[botType].botType)}
+      className={`card admin-bot-card rounded border-radius-sm shadow ${props.isActive ? 'border-primary' : ''}`}
+      onClick={() => props.onBotTypeSelectHandler(botDetails[props.botType].botType)}
       role="button"
-      key={botType}
+      key={props.botType}
     >
       <div>
         <h3 className={`card-header mb-0 py-3
               ${isBotTypeOfficial ? 'd-flex align-items-center justify-content-center' : 'text-center'}
-              ${isActive ? 'bg-primary grw-botcard-title-active' : ''}`}
+              ${props.isActive ? 'bg-primary grw-botcard-title-active' : ''}`}
         >
           <span className="me-2">
-            {t(`admin:slack_integration.selecting_bot_types.${botDetails[botType].botTypeCategory}`)}
+            {t(`admin:slack_integration.selecting_bot_types.${botDetails[props.botType].botTypeCategory}`)}
           </span>
 
           {/*  A recommended badge is shown on official bot card, supplementary names are shown on Custom bot cards   */}
@@ -67,48 +59,40 @@ export const BotTypeCard = (props: BotTypeCardProps): JSX.Element => {
               </span>
             ) : (
               <span className="supplementary-bot-name me-2">
-                {t(`admin:slack_integration.selecting_bot_types.${botDetails[botType].supplementaryBotName}`)}
+                {t(`admin:slack_integration.selecting_bot_types.${botDetails[props.botType].supplementaryBotName}`)}
               </span>
             )}
 
-          <i className={isActive ? 'grw-botcard-title-active' : ''} aria-hidden="true"></i>
+          <i className={props.isActive ? 'grw-botcard-title-active' : ''} aria-hidden="true"></i>
         </h3>
       </div>
       <div className="card-body p-4">
         <div className="card-text">
           <div className="my-2">
-            <Image
+            <img
               className="bot-difficulty-icon d-block mx-auto mb-4"
-              src={`/images/slack-integration/slackbot-difficulty-level-${botDetails[botType].setUp}.svg`}
-              alt=""
-              width={60}
-              height={60}
+              src={`/images/slack-integration/slackbot-difficulty-level-${botDetails[props.botType].setUp}.svg`}
             />
-            <div className="d-flex justify-content-between mb-3 align-items-center">
+            <div className="d-flex justify-content-between mb-3">
               <span>{t('admin:slack_integration.selecting_bot_types.multiple_workspaces_integration')}</span>
-              <Image
-                className="bot-type-disc"
-                src={`/images/slack-integration/${botDetails[botType].multiWSIntegration}.png`}
-                alt=""
-                width={20}
-                height={20}
-              />
+              <img className="bot-type-disc" src={`/images/slack-integration/${botDetails[props.botType].multiWSIntegration}.png`} alt="" />
             </div>
-            <div className="d-flex justify-content-between align-items-center">
+            <div className="d-flex justify-content-between">
               <span>{t('admin:slack_integration.selecting_bot_types.security_control')}</span>
-              <Image
-                className="bot-type-disc"
-                src={`/images/slack-integration/${botDetails[botType].securityControl}.png`}
-                alt=""
-                width={20}
-                height={20}
-              />
+              <img className="bot-type-disc" src={`/images/slack-integration/${botDetails[props.botType].securityControl}.png`} alt="" />
             </div>
           </div>
         </div>
       </div>
     </div>
   );
+
+};
+
+BotTypeCard.propTypes = {
+  isActive: PropTypes.bool.isRequired,
+  botType: PropTypes.string.isRequired,
+  onBotTypeSelectHandler: PropTypes.func.isRequired,
 };
 
-BotTypeCard.displayName = 'BotTypeCard';
+export default BotTypeCard;

+ 21 - 17
apps/app/src/components/Admin/SlackIntegration/Bridge.tsx → apps/app/src/components/Admin/SlackIntegration/Bridge.jsx

@@ -1,24 +1,19 @@
+import React from 'react';
 
 import { useTranslation } from 'next-i18next';
+import PropTypes from 'prop-types';
 import { UncontrolledTooltip } from 'reactstrap';
 
 const ProxyCircle = () => (
   <div className="grw-bridge-proxy-circle">
-    <div className="circle bg-primary border-light rounded-circle">
+    <div className="circle position-absolute bg-primary border-light rounded-circle">
       <p className="circle-inner text-light fw-bold d-none d-lg-inline">Proxy Server</p>
-      <p className="circle-inner grw-proxy-server-name d-inline d-lg-none">Proxy Server</p>
+      <p className="circle-inner grw-proxy-server-name d-block d-lg-none">Proxy Server</p>
     </div>
   </div>
 );
 
-type BridgeCoreProps = {
-  description: string,
-  iconClass: string,
-  iconName: string,
-  hrClass: string,
-  withProxy?: boolean,
-}
-const BridgeCore = (props: BridgeCoreProps): JSX.Element => {
+const BridgeCore = (props) => {
   const {
     description, iconClass, iconName, hrClass, withProxy,
   } = props;
@@ -49,13 +44,16 @@ const BridgeCore = (props: BridgeCoreProps): JSX.Element => {
   );
 };
 
+BridgeCore.propTypes = {
+  description: PropTypes.string.isRequired,
+  iconClass: PropTypes.string.isRequired,
+  iconName: PropTypes.string.isRequired,
+  hrClass: PropTypes.string.isRequired,
+  withProxy: PropTypes.bool,
+};
+
 
-type BridgeProps = {
-  errorCount: number,
-  totalCount: number,
-  withProxy?: boolean,
-}
-export const Bridge = (props: BridgeProps): JSX.Element => {
+const Bridge = (props) => {
   const { t } = useTranslation();
   const { errorCount, totalCount, withProxy } = props;
 
@@ -97,4 +95,10 @@ export const Bridge = (props: BridgeProps): JSX.Element => {
   );
 };
 
-Bridge.displayName = 'Bridge';
+Bridge.propTypes = {
+  errorCount: PropTypes.number.isRequired,
+  totalCount: PropTypes.number.isRequired,
+  withProxy: PropTypes.bool,
+};
+
+export default Bridge;

+ 57 - 0
apps/app/src/components/Admin/SlackIntegration/CustomBotWithProxyConnectionStatus.jsx

@@ -0,0 +1,57 @@
+import React from 'react';
+
+import PropTypes from 'prop-types';
+
+import Bridge from './Bridge';
+
+const CustomBotWithProxyConnectionStatus = (props) => {
+  const { siteName, connectionStatuses } = props;
+
+  const connectionStatusValues = Object.values(connectionStatuses); // type: ConnectionStatus[]
+
+  const totalCount = connectionStatusValues.length;
+  const errorCount = connectionStatusValues.filter(connectionStatus => connectionStatusValues.error != null).length;
+
+  return (
+    <div className="d-flex justify-content-center my-5 bot-integration">
+
+      <div className="card rounded shadow border-0 w-50 admin-bot-card">
+        <h5 className="card-title fw-bold mt-3 ms-3">Slack</h5>
+        <div className="card-body px-5">
+          {connectionStatusValues.map((connectionStatus, i) => {
+            const workspaceName = connectionStatus.workspaceName || `Settings #${i}`;
+
+            return (
+              <div key={workspaceName} className="card slack-work-space-name-card">
+                <div className="m-2 text-center">
+                  <h5 className="fw-bold">{workspaceName}</h5>
+                  <img width={20} height={20} src="/images/slack-integration/growi-bot-kun-icon.png" />
+                </div>
+              </div>
+            );
+          })}
+        </div>
+      </div>
+
+      <div className="text-center w-25 mt-3">
+        <Bridge errorCount={errorCount} totalCount={totalCount} withProxy />
+      </div>
+
+      <div className="card rounded-3 shadow border-0 w-50 admin-bot-card">
+        <h5 className="card-title fw-bold mt-3 ms-3">GROWI App</h5>
+        <div className="card-body text-center">
+          <div className="mx-md-3 my-4 my-lg-5 p-2 border bg-primary text-light">
+            {siteName}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+
+CustomBotWithProxyConnectionStatus.propTypes = {
+  siteName: PropTypes.string.isRequired,
+  connectionStatuses: PropTypes.object.isRequired,
+};
+
+export default CustomBotWithProxyConnectionStatus;

+ 0 - 59
apps/app/src/components/Admin/SlackIntegration/CustomBotWithProxyConnectionStatus.tsx

@@ -1,59 +0,0 @@
-import React from 'react';
-
-import type { ConnectionStatus } from '@growi/slack';
-import Image from 'next/image';
-
-import { Bridge } from './Bridge';
-
-
-type CustomBotWithProxyConnectionStatusProps = {
-  siteName: string,
-  connectionStatuses: any,
-}
-
-export const CustomBotWithProxyConnectionStatus = (props: CustomBotWithProxyConnectionStatusProps): JSX.Element => {
-  const { siteName, connectionStatuses } = props;
-
-  const connectionStatusValues: ConnectionStatus[] = Object.values(connectionStatuses);
-
-  const totalCount = connectionStatusValues.length;
-  const errorCount = connectionStatusValues.filter(connectionStatus => connectionStatus.error != null).length;
-
-  return (
-    <div className="row justify-content-center my-5 bot-integration">
-
-      <div className="card rounded shadow col-4 border-0 admin-bot-card">
-        <h5 className="card-title fw-bold mt-3 text-center">Slack</h5>
-        <div className="card-body px-5">
-          {connectionStatusValues.map((connectionStatus, i) => {
-            const workspaceName = connectionStatus.workspaceName || `Settings #${i}`;
-
-            return (
-              <div key={workspaceName} className="card slack-work-space-name-card">
-                <div className="m-2 text-center">
-                  <h5 className="fw-bold">{workspaceName}</h5>
-                  <Image width={20} height={20} src="/images/slack-integration/growi-bot-kun-icon.png" alt="" />
-                </div>
-              </div>
-            );
-          })}
-        </div>
-      </div>
-
-      <div className="col-3 mt-3 text-center">
-        <Bridge errorCount={errorCount} totalCount={totalCount} withProxy />
-      </div>
-
-      <div className="card rounded-3 shadow col-4 border-0 admin-bot-card">
-        <h5 className="card-title fw-bold mt-3 text-center">GROWI App</h5>
-        <div className="card-body text-center">
-          <div className="mx-md-3 my-4 my-lg-5 p-2 border bg-primary text-light">
-            {siteName}
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-};
-
-CustomBotWithProxyConnectionStatus.displayName = 'CustomBotWithProxyConnectionStatus';

+ 2 - 2
apps/app/src/components/Admin/SlackIntegration/CustomBotWithProxySettings.jsx

@@ -9,8 +9,8 @@ import { useAppTitle } from '~/stores/context';
 import loggerFactory from '~/utils/logger';
 
 
-import { CustomBotWithProxyConnectionStatus } from './CustomBotWithProxyConnectionStatus';
-import { DeleteSlackBotSettingsModal } from './DeleteSlackBotSettingsModal';
+import CustomBotWithProxyConnectionStatus from './CustomBotWithProxyConnectionStatus';
+import DeleteSlackBotSettingsModal from './DeleteSlackBotSettingsModal';
 import { SlackAppIntegrationControl } from './SlackAppIntegrationControl';
 import WithProxyAccordions from './WithProxyAccordions';
 

+ 57 - 0
apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxyConnectionStatus.jsx

@@ -0,0 +1,57 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Bridge from './Bridge';
+
+const CustomBotWithoutProxyConnectionStatus = (props) => {
+  const { siteName, connectionStatuses } = props;
+
+  const connectionStatusValues = Object.values(connectionStatuses); // type: ConnectionStatus[]
+
+  const totalCount = connectionStatusValues.length;
+  const errorCount = connectionStatusValues.filter(connectionStatus => connectionStatus.error != null).length;
+
+  let workspaceName;
+  if (totalCount > 0) {
+    workspaceName = connectionStatusValues[0].workspaceName;
+  }
+
+  return (
+    <div className="d-flex justify-content-center my-5 bot-integration">
+      <div className="card rounded shadow border-0 w-50 admin-bot-card mb-0">
+        <h5 className="card-title fw-bold mt-3 ms-4">Slack</h5>
+        <div className="card-body px-4 text-center mx-md-5">
+          {totalCount > 0 ? (
+            <div className="card slack-work-space-name-card">
+              <div className="m-2 text-center">
+                <h5 className="fw-bold">
+                  {workspaceName != null ? workspaceName : 'Settings #1'}
+                </h5>
+                <img width={20} height={20} src="/images/slack-integration/growi-bot-kun-icon.png" />
+              </div>
+            </div>
+          ) : ''}
+        </div>
+      </div>
+
+      <div className="text-center w-25">
+        <Bridge errorCount={errorCount} totalCount={totalCount} />
+      </div>
+
+      <div className="card rounded-3 shadow border-0 w-50 admin-bot-card mb-0">
+        <h5 className="card-title fw-bold mt-3 ms-4">GROWI App</h5>
+        <div className="card-body p-4 text-center">
+          <div className="border p-2 bg-primary text-light mx-md-5">
+            {siteName}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+
+CustomBotWithoutProxyConnectionStatus.propTypes = {
+  siteName: PropTypes.string.isRequired,
+  connectionStatuses: PropTypes.object.isRequired,
+};
+
+export default CustomBotWithoutProxyConnectionStatus;

+ 0 - 57
apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxyConnectionStatus.tsx

@@ -1,57 +0,0 @@
-import React from 'react';
-
-import type { ConnectionStatus } from '@growi/slack';
-import Image from 'next/image';
-
-import { Bridge } from './Bridge';
-
-type CustomBotWithoutProxyConnectionStatusProps = {
-  siteName: string,
-  connectionStatuses: any,
-}
-
-export const CustomBotWithoutProxyConnectionStatus = (props: CustomBotWithoutProxyConnectionStatusProps): JSX.Element => {
-  const { siteName, connectionStatuses } = props;
-
-  const connectionStatusValues: ConnectionStatus[] = Object.values(connectionStatuses);
-
-  const totalCount = connectionStatusValues.length;
-  const errorCount = connectionStatusValues.filter(connectionStatus => connectionStatus.error != null).length;
-  const workspaceName = connectionStatusValues[0]?.workspaceName;
-
-  return (
-    <div className="row justify-content-center my-5 bot-integration">
-      <div className="card rounded shadow col-4 border-0 admin-bot-card mb-0">
-        <h5 className="card-title fw-bold mt-3 text-center">Slack</h5>
-        <div className="card-body px-4 text-center mx-md-5">
-          {totalCount > 0 ? (
-            <div className="card slack-work-space-name-card">
-              <div className="m-2 text-center">
-                <h5 className="fw-bold">
-                  {workspaceName != null ? workspaceName : 'Settings #1'}
-                </h5>
-                <Image width={20} height={20} src="/images/slack-integration/growi-bot-kun-icon.png" alt="" />
-              </div>
-            </div>
-          ) : ''}
-        </div>
-      </div>
-
-      <div className="col-3 text-center">
-        <Bridge errorCount={errorCount} totalCount={totalCount} />
-      </div>
-
-      <div className="card rounded-3 shadow col-4 border-0 admin-bot-card mb-0">
-        <h5 className="card-title fw-bold mt-3 text-center">GROWI App</h5>
-        <div className="card-body p-4 text-center">
-          <div className="border p-2 bg-primary text-light mx-md-5">
-            {siteName}
-          </div>
-        </div>
-      </div>
-
-    </div>
-  );
-};
-
-CustomBotWithoutProxyConnectionStatus.displayName = 'CustomBotWithoutProxyConnectionStatus';

+ 1 - 1
apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettings.jsx

@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
 
 import { useAppTitle } from '~/stores/context';
 
-import { CustomBotWithoutProxyConnectionStatus } from './CustomBotWithoutProxyConnectionStatus';
+import CustomBotWithoutProxyConnectionStatus from './CustomBotWithoutProxyConnectionStatus';
 import CustomBotWithoutProxySettingsAccordion, { botInstallationStep } from './CustomBotWithoutProxySettingsAccordion';
 
 const CustomBotWithoutProxySettings = (props) => {

+ 1 - 1
apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx

@@ -10,7 +10,7 @@ import Accordion from '../Common/Accordion';
 import CustomBotWithoutProxySecretTokenSection from './CustomBotWithoutProxySecretTokenSection';
 import ManageCommandsProcessWithoutProxy from './ManageCommandsProcessWithoutProxy';
 import MessageBasedOnConnection from './MessageBasedOnConnection';
-import { addLogs } from './slack-integration-util';
+import { addLogs } from './slak-integration-util';
 
 
 export const botInstallationStep = {

+ 19 - 21
apps/app/src/components/Admin/SlackIntegration/DeleteSlackBotSettingsModal.tsx → apps/app/src/components/Admin/SlackIntegration/DeleteSlackBotSettingsModal.jsx

@@ -1,24 +1,13 @@
 import React, { useCallback } from 'react';
 
 import { useTranslation } from 'next-i18next';
+import PropTypes from 'prop-types';
 import {
   Button, Modal, ModalHeader, ModalBody, ModalFooter,
 } from 'reactstrap';
 
-type DeleteSlackBotSettingsModalProps = {
-  isResetAll: boolean,
-  isOpen: boolean,
-  onClose?: () => void,
-  onClickDeleteButton?: () => void,
-}
-
-export const DeleteSlackBotSettingsModal = React.memo((props: DeleteSlackBotSettingsModalProps) => {
-
-  const { t } = useTranslation();
-
-  const {
-    isResetAll, isOpen, onClose, onClickDeleteButton,
-  } = props;
+const DeleteSlackBotSettingsModal = React.memo((props) => {
+  const { t, onClickDeleteButton, onClose } = useTranslation();
 
   const deleteSlackCredentialsHandler = useCallback(() => {
     onClickDeleteButton?.();
@@ -30,16 +19,16 @@ export const DeleteSlackBotSettingsModal = React.memo((props: DeleteSlackBotSett
   }, [onClose]);
 
   return (
-    <Modal isOpen={isOpen} toggle={closeButtonHandler} className="page-comment-delete-modal">
+    <Modal isOpen={props.isOpen} toggle={closeButtonHandler} className="page-comment-delete-modal">
       <ModalHeader tag="h4" toggle={closeButtonHandler} className="bg-danger text-light">
         <span>
-          {isResetAll && (
+          {props.isResetAll && (
             <>
               <span className="material-symbols-outlined">delete_forever</span>
               {t('admin:slack_integration.reset_all_settings')}
             </>
           )}
-          {!isResetAll && (
+          {!props.isResetAll && (
             <>
               <span className="material-symbols-outlined">delete</span>
               {t('admin:slack_integration.delete_slackbot_settings')}
@@ -48,13 +37,13 @@ export const DeleteSlackBotSettingsModal = React.memo((props: DeleteSlackBotSett
         </span>
       </ModalHeader>
       <ModalBody>
-        {isResetAll && (
+        {props.isResetAll && (
           <span
             // eslint-disable-next-line react/no-danger
             dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.all_settings_of_the_bot_will_be_reset') }}
           />
         )}
-        {!isResetAll && (
+        {!props.isResetAll && (
           <span
             // eslint-disable-next-line react/no-danger
             dangerouslySetInnerHTML={{ __html: t('admin:slack_integration.slackbot_settings_notice') }}
@@ -64,13 +53,13 @@ export const DeleteSlackBotSettingsModal = React.memo((props: DeleteSlackBotSett
       <ModalFooter>
         <Button onClick={closeButtonHandler}>{t('Cancel')}</Button>
         <Button color="danger" onClick={deleteSlackCredentialsHandler}>
-          {isResetAll && (
+          {props.isResetAll && (
             <>
               <span className="material-symbols-outlined">delete_forever</span>
               {t('admin:slack_integration.reset')}
             </>
           )}
-          {!isResetAll && (
+          {!props.isResetAll && (
             <>
               <span className="material-symbols-outlined">delete</span>
               {t('admin:slack_integration.delete')}
@@ -83,4 +72,13 @@ export const DeleteSlackBotSettingsModal = React.memo((props: DeleteSlackBotSett
 
 });
 
+DeleteSlackBotSettingsModal.propTypes = {
+  isResetAll: PropTypes.bool.isRequired,
+  isOpen: PropTypes.bool.isRequired,
+  onClose: PropTypes.func,
+  onClickDeleteButton: PropTypes.func,
+};
+
 DeleteSlackBotSettingsModal.displayName = 'DeleteSlackBotSettingsModal';
+
+export default DeleteSlackBotSettingsModal;

+ 2 - 2
apps/app/src/components/Admin/SlackIntegration/OfficialBotSettings.jsx

@@ -11,8 +11,8 @@ import { useAppTitle } from '~/stores/context';
 import loggerFactory from '~/utils/logger';
 
 
-import { CustomBotWithProxyConnectionStatus } from './CustomBotWithProxyConnectionStatus';
-import { DeleteSlackBotSettingsModal } from './DeleteSlackBotSettingsModal';
+import CustomBotWithProxyConnectionStatus from './CustomBotWithProxyConnectionStatus';
+import DeleteSlackBotSettingsModal from './DeleteSlackBotSettingsModal';
 import { SlackAppIntegrationControl } from './SlackAppIntegrationControl';
 import WithProxyAccordions from './WithProxyAccordions';
 

+ 2 - 1
apps/app/src/components/Admin/SlackIntegration/SlackAppIntegrationControl.tsx

@@ -1,3 +1,4 @@
+import React, { FC } from 'react';
 
 import { useTranslation } from 'next-i18next';
 
@@ -10,7 +11,7 @@ type Props = {
   onDeleteButtonClicked?: (slackAppIntegration: unknown) => void,
 }
 
-export const SlackAppIntegrationControl = (props: Props): JSX.Element => {
+export const SlackAppIntegrationControl: FC<Props> = (props: Props) => {
   const { t } = useTranslation();
 
   const { slackAppIntegration, onIsPrimaryChanged, onDeleteButtonClicked } = props;

+ 12 - 12
apps/app/src/components/Admin/SlackIntegration/SlackIntegration.tsx → apps/app/src/components/Admin/SlackIntegration/SlackIntegration.jsx

@@ -10,21 +10,21 @@ import {
 import { toastSuccess, toastError } from '~/client/util/toastr';
 import { LoadingSpinner } from '~/components/LoadingSpinner';
 
-import { BotTypeCard } from './BotTypeCard';
+import BotTypeCard from './BotTypeCard';
 import ConfirmBotChangeModal from './ConfirmBotChangeModal';
 import CustomBotWithProxySettings from './CustomBotWithProxySettings';
 import CustomBotWithoutProxySettings from './CustomBotWithoutProxySettings';
-import { DeleteSlackBotSettingsModal } from './DeleteSlackBotSettingsModal';
+import DeleteSlackBotSettingsModal from './DeleteSlackBotSettingsModal';
 import OfficialBotSettings from './OfficialBotSettings';
 
 
 const botTypes = Object.values(SlackbotType);
 
-export const SlackIntegration = (): JSX.Element => {
+const SlackIntegration = () => {
 
   const { t } = useTranslation();
-  const [currentBotType, setCurrentBotType] = useState<SlackbotType | undefined>();
-  const [selectedBotType, setSelectedBotType] = useState<SlackbotType | undefined>();
+  const [currentBotType, setCurrentBotType] = useState(null);
+  const [selectedBotType, setSelectedBotType] = useState(null);
   const [slackSigningSecret, setSlackSigningSecret] = useState(null);
   const [slackBotToken, setSlackBotToken] = useState(null);
   const [slackSigningSecretEnv, setSlackSigningSecretEnv] = useState('');
@@ -106,12 +106,12 @@ export const SlackIntegration = (): JSX.Element => {
     fetchSlackIntegrationData();
   }, [fetchSlackIntegrationData]);
 
-  const changeCurrentBotSettings = async(botType?: SlackbotType) => {
+  const changeCurrentBotSettings = async(botType) => {
     try {
       await apiv3Put('/slack-integration-settings/bot-type', {
         currentBotType: botType,
       });
-      setSelectedBotType(undefined);
+      setSelectedBotType(null);
       fetchSlackIntegrationData();
     }
     catch (err) {
@@ -119,7 +119,7 @@ export const SlackIntegration = (): JSX.Element => {
     }
   };
 
-  const botTypeSelectHandler = async(botType: SlackbotType) => {
+  const botTypeSelectHandler = async(botType) => {
     if (botType === currentBotType) {
       return;
     }
@@ -135,10 +135,10 @@ export const SlackIntegration = (): JSX.Element => {
   };
 
   const cancelBotChangeHandler = () => {
-    setSelectedBotType(undefined);
+    setSelectedBotType(null);
   };
 
-  let settingsComponent = <></>;
+  let settingsComponent = null;
 
   switch (currentBotType) {
     case SlackbotType.OFFICIAL:
@@ -231,7 +231,7 @@ export const SlackIntegration = (): JSX.Element => {
           </button>
         </div>
 
-        <div className="my-5 d-flex flex-wrap-reverse justify-content-center">
+        <div className="row my-5 flex-wrap-reverse justify-content-center">
           {botTypes.map((botType) => {
             return (
               <div key={botType} className="m-3">
@@ -251,4 +251,4 @@ export const SlackIntegration = (): JSX.Element => {
   );
 };
 
-SlackIntegration.displayName = 'SlackIntegration';
+export default SlackIntegration;

+ 1 - 1
apps/app/src/components/Admin/SlackIntegration/WithProxyAccordions.jsx

@@ -15,7 +15,7 @@ import Accordion from '../Common/Accordion';
 
 import ManageCommandsProcess from './ManageCommandsProcess';
 import MessageBasedOnConnection from './MessageBasedOnConnection';
-import { addLogs } from './slack-integration-util';
+import { addLogs } from './slak-integration-util';
 
 const logger = loggerFactory('growi:SlackIntegration:WithProxyAccordionsWrapper');
 

+ 0 - 4
apps/app/src/components/Admin/SlackIntegration/slack-integration-util.ts

@@ -1,4 +0,0 @@
-export const addLogs = (log: string, newLogMessage:string, newLogCode?: string): string => {
-  const newLog = `${new Date()} - ${newLogCode ? `${newLogCode}, ` : ''}${newLogMessage}\n\n`;
-  return `${newLog}${log ?? ''}`;
-};

+ 20 - 0
apps/app/src/components/Admin/SlackIntegration/slak-integration-util.js

@@ -0,0 +1,20 @@
+const addLogs = (log, newLogMessage, newLogCode = undefined) => {
+
+  let newLog;
+  if (newLogCode == null) {
+    newLog = `${new Date()} - ${newLogMessage}\n\n`;
+  }
+  else {
+    newLog = `${new Date()} - ${newLogCode}, ${newLogMessage}\n\n`;
+  }
+
+  if (log == null) {
+    return newLog;
+  }
+  return `${newLog}${log}`;
+};
+
+export {
+  // eslint-disable-next-line import/prefer-default-export
+  addLogs,
+};

+ 7 - 13
apps/app/src/components/Layout/Admin.module.scss

@@ -95,12 +95,9 @@ $slack-work-space-name-card-border: #efc1f6;
       font-size: 0.6rem;
     }
     .admin-bot-card {
-      min-width: 300px;
+      min-width: 280px;
       max-width: 500px;
       border-radius: 8px !important;
-      .grw-botcard-title-active {
-        color: $gray-200;
-      }
     }
     .border-primary {
       border-width: 2px;
@@ -137,17 +134,13 @@ $slack-work-space-name-card-border: #efc1f6;
     }
 
     .grw-bridge-proxy-circle {
-      position: relative;
       .circle {
-        position: absolute;
-        inset:0;
-        z-index: 1;
+        left: 50%;
         width: 100px;
         height: 100px;
-        margin:auto;
         border: 13px solid;
-
-        @include media-breakpoint-down(lg) {
+        transform: translate(-50%, -50%);
+        @include media-breakpoint-down(md) {
           width: 50px;
           height: 50px;
           border: 8px solid;
@@ -156,11 +149,12 @@ $slack-work-space-name-card-border: #efc1f6;
 
       .circle-inner {
         position: absolute;
-        transform: translate(-50%, 25%);
+        top: 50%;
+        left: 50%;
+        transform: translate(-50%, -50%);
       }
       .circle-inner.grw-proxy-server-name {
         margin-top: 55px;
-        transform: translate(-50%, -25%);
       }
     }
 

+ 4 - 5
apps/app/src/pages/admin/slack-integration.page.tsx

@@ -1,20 +1,19 @@
-import type {
+import {
   NextPage, GetServerSideProps, GetServerSidePropsContext,
 } from 'next';
 import { useTranslation } from 'next-i18next';
 import dynamic from 'next/dynamic';
 import Head from 'next/head';
 
-import type { CrowiRequest } from '~/interfaces/crowi-request';
-import type { CommonProps } from '~/pages/utils/commons';
-import { generateCustomTitle } from '~/pages/utils/commons';
+import { CrowiRequest } from '~/interfaces/crowi-request';
+import { CommonProps, generateCustomTitle } from '~/pages/utils/commons';
 import { useCurrentUser, useSiteUrl } from '~/stores/context';
 
 import { retrieveServerSideProps } from '../../utils/admin-page-util';
 
 
 const AdminLayout = dynamic(() => import('~/components/Layout/AdminLayout'), { ssr: false });
-const SlackIntegration = dynamic(() => import('~/components/Admin/SlackIntegration/SlackIntegration').then(mod => mod.SlackIntegration), { ssr: false });
+const SlackIntegration = dynamic(() => import('~/components/Admin/SlackIntegration/SlackIntegration'), { ssr: false });
 const ForbiddenPage = dynamic(() => import('~/components/Admin/ForbiddenPage').then(mod => mod.ForbiddenPage), { ssr: false });
 
 

+ 0 - 1
packages/slack/src/interfaces/index.ts

@@ -1,5 +1,4 @@
 export * from './channel';
-export * from './connection-status';
 export * from './growi-command-processor';
 export * from './growi-interaction-processor';
 export * from './growi-event-processor';