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

Merge pull request #3080 from weseek/fix/4302-4436-api-runs-more-than-necessary-at-security-page

Fix/4302 4436 api runs more than necessary at security page
Yuki Takei 5 лет назад
Родитель
Сommit
77889f330b

+ 29 - 6
src/client/js/components/Admin/Notification/NotificationSetting.jsx

@@ -1,8 +1,9 @@
-import React, { useMemo } from 'react';
+import React, { useMemo, useState } from 'react';
 import PropTypes from 'prop-types';
 
 import loggerFactory from '@alias/logger';
 
+import { TabContent, TabPane } from 'reactstrap';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { toastError } from '../../../util/apiNotification';
 import toArrayIfNot from '../../../../../lib/util/toArrayIfNot';
@@ -10,7 +11,7 @@ import { withLoadingSppiner } from '../../SuspenseUtils';
 
 import AdminNotificationContainer from '../../../services/AdminNotificationContainer';
 
-import CustomNavigation from '../../CustomNavigation';
+import { CustomNav } from '../../CustomNavigation';
 
 import SlackAppConfiguration from './SlackAppConfiguration';
 import UserTriggerNotification from './UserTriggerNotification';
@@ -21,6 +22,15 @@ const logger = loggerFactory('growi:NotificationSetting');
 let retrieveErrors = null;
 function NotificationSetting(props) {
   const { adminNotificationContainer } = props;
+
+  const [activeTab, setActiveTab] = useState('slack_configuration');
+  const [activeComponents, setActiveComponents] = useState(new Set(['slack_configuration']));
+
+  const switchActiveTab = (selectedTab) => {
+    setActiveTab(selectedTab);
+    setActiveComponents(activeComponents.add(selectedTab));
+  };
+
   if (adminNotificationContainer.state.webhookUrl === adminNotificationContainer.dummyWebhookUrl) {
     throw (async() => {
       try {
@@ -44,26 +54,39 @@ function NotificationSetting(props) {
     return {
       slack_configuration: {
         Icon: () => <i className="icon-settings" />,
-        Content: SlackAppConfiguration,
         i18n: 'Slack configuration',
         index: 0,
       },
       user_trigger_notification: {
         Icon: () => <i className="icon-settings" />,
-        Content: UserTriggerNotification,
         i18n: 'User trigger notification',
         index: 1,
       },
       global_notification: {
         Icon: () => <i className="icon-settings" />,
-        Content: GlobalNotification,
         i18n: 'Global notification',
         index: 2,
       },
     };
   }, []);
 
-  return <CustomNavigation navTabMapping={navTabMapping} />;
+  return (
+    <>
+      <CustomNav activeTab={activeTab} navTabMapping={navTabMapping} onNavSelected={switchActiveTab} hideBorderBottom />
+
+      <TabContent activeTab={activeTab} className="p-5">
+        <TabPane tabId="slack_configuration">
+          {activeComponents.has('slack_configuration') && <SlackAppConfiguration />}
+        </TabPane>
+        <TabPane tabId="user_trigger_notification">
+          {activeComponents.has('user_trigger_notification') && <UserTriggerNotification />}
+        </TabPane>
+        <TabPane tabId="global_notification">
+          {activeComponents.has('global_notification') && <GlobalNotification />}
+        </TabPane>
+      </TabContent>
+    </>
+  );
 }
 
 const NotificationSettingWithUnstatedContainer = withUnstatedContainers(withLoadingSppiner(NotificationSetting), [AdminNotificationContainer]);

+ 42 - 12
src/client/js/components/Admin/Security/SecurityManagementContents.jsx

@@ -1,7 +1,9 @@
-import React, { Fragment, useMemo } from 'react';
+import React, { Fragment, useMemo, useState } from 'react';
 import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 
+import { TabContent, TabPane } from 'reactstrap';
+
 import LdapSecuritySetting from './LdapSecuritySetting';
 import LocalSecuritySetting from './LocalSecuritySetting';
 import SamlSecuritySetting from './SamlSecuritySetting';
@@ -14,64 +16,63 @@ import TwitterSecuritySetting from './TwitterSecuritySetting';
 import FacebookSecuritySetting from './FacebookSecuritySetting';
 import ShareLinkSetting from './ShareLinkSetting';
 
-import CustomNavigation from '../../CustomNavigation';
+import { CustomNav } from '../../CustomNavigation';
 
 function SecurityManagementContents(props) {
   const { t } = props;
 
+  const [activeTab, setActiveTab] = useState('passport_local');
+  const [activeComponents, setActiveComponents] = useState(new Set(['passport_local']));
+
+  const switchActiveTab = (selectedTab) => {
+    setActiveTab(selectedTab);
+    setActiveComponents(activeComponents.add(selectedTab));
+  };
+
   const navTabMapping = useMemo(() => {
     return {
       passport_local: {
         Icon: () => <i className="fa fa-users" />,
-        Content: LocalSecuritySetting,
         i18n: 'ID/Pass',
         index: 0,
       },
       passport_ldap: {
         Icon: () => <i className="fa fa-sitemap" />,
-        Content: LdapSecuritySetting,
         i18n: 'LDAP',
         index: 1,
       },
       passport_saml: {
         Icon: () => <i className="fa fa-key" />,
-        Content: SamlSecuritySetting,
         i18n: 'SAML',
         index: 2,
       },
       passport_oidc: {
         Icon: () => <i className="fa fa-key" />,
-        Content: OidcSecuritySetting,
         i18n: 'OIDC',
         index: 3,
       },
       passport_basic: {
         Icon: () => <i className="fa fa-lock" />,
-        Content: BasicSecuritySetting,
         i18n: 'BASIC',
         index: 4,
       },
       passport_google: {
         Icon: () => <i className="fa fa-google" />,
-        Content: GoogleSecuritySetting,
         i18n: 'Google',
         index: 5,
       },
       passport_github: {
         Icon: () => <i className="fa fa-github" />,
-        Content: GitHubSecuritySetting,
         i18n: 'GitHub',
         index: 6,
       },
       passport_twitter: {
         Icon: () => <i className="fa fa-twitter" />,
-        Content: TwitterSecuritySetting,
         i18n: 'Twitter',
         index: 7,
       },
       passport_facebook: {
         Icon: () => <i className="fa fa-facebook" />,
-        Content: FacebookSecuritySetting,
         i18n: '(TBD) Facebook',
         index: 8,
       },
@@ -103,7 +104,36 @@ function SecurityManagementContents(props) {
 
       <div className="auth-mechanism-configurations">
         <h2 className="border-bottom">{t('security_setting.Authentication mechanism settings')}</h2>
-        <CustomNavigation navTabMapping={navTabMapping} />
+        <CustomNav activeTab={activeTab} navTabMapping={navTabMapping} onNavSelected={switchActiveTab} hideBorderBottom />
+        <TabContent activeTab={activeTab} className="p-5">
+          <TabPane tabId="passport_local">
+            {activeComponents.has('passport_local') && <LocalSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_ldap">
+            {activeComponents.has('passport_ldap') && <LdapSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_saml">
+            {activeComponents.has('passport_saml') && <SamlSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_oidc">
+            {activeComponents.has('passport_oidc') && <OidcSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_basic">
+            {activeComponents.has('passport_basic') && <BasicSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_google">
+            {activeComponents.has('passport_google') && <GoogleSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_github">
+            {activeComponents.has('passport_github') && <GitHubSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_twitter">
+            {activeComponents.has('passport_twitter') && <TwitterSecuritySetting />}
+          </TabPane>
+          <TabPane tabId="passport_facebook">
+            {activeComponents.has('passport_facebook') && <FacebookSecuritySetting />}
+          </TabPane>
+        </TabContent>
       </div>
     </Fragment>
   );