Taichi Masuyama 4 лет назад
Родитель
Сommit
2e4614d782

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

@@ -58,6 +58,8 @@ export default class AdminAppContainer extends Container {
       s3ReferenceFileWithRelayMode: false,
 
       isEnabledPlugins: true,
+
+      isMaintenanceMode: false,
     };
 
   }
@@ -116,6 +118,7 @@ export default class AdminAppContainer extends Container {
       envGcsBucket: appSettingsParams.envGcsBucket,
       envGcsUploadNamespace: appSettingsParams.envGcsUploadNamespace,
       isEnabledPlugins: appSettingsParams.isEnabledPlugins,
+      isMaintenanceMode: appSettingsParams.isMaintenanceMode,
     });
 
     // if useOnlyEnvVarForFileUploadType is true, get fileUploadType from only env var and make the forms fixed.

+ 12 - 8
packages/app/src/components/Admin/App/V5PageMigrationModal.tsx → packages/app/src/components/Admin/App/ConfirmModal.tsx

@@ -3,14 +3,18 @@ import {
   Modal, ModalHeader, ModalBody, ModalFooter,
 } from 'reactstrap';
 import { useTranslation } from 'react-i18next';
+import { TFunctionResult } from 'i18next';
 
-type V5PageMigrationModalProps = {
+type ConfirmModalProps = {
   isModalOpen: boolean
-  onConfirm?: () => Promise<void>;
-  onCancel?: () => void;
+  warningMessage: TFunctionResult
+  supplymentaryMessage: TFunctionResult
+  confirmButtonTitle: TFunctionResult
+  onConfirm?: () => Promise<void>
+  onCancel?: () => void
 };
 
-export const V5PageMigrationModal: FC<V5PageMigrationModalProps> = (props: V5PageMigrationModalProps) => {
+export const ConfirmModal: FC<ConfirmModalProps> = (props: ConfirmModalProps) => {
   const { t } = useTranslation();
 
   const onCancel = () => {
@@ -29,15 +33,15 @@ export const V5PageMigrationModal: FC<V5PageMigrationModalProps> = (props: V5Pag
     <Modal isOpen={props.isModalOpen} toggle={onCancel} className="">
       <ModalHeader tag="h4" toggle={onCancel} className="bg-warning">
         <i className="icon-fw icon-question" />
-        Warning
+        {t('Warning')}
       </ModalHeader>
       <ModalBody>
-        {t('admin:v5_page_migration.modal_migration_warning')}
+        {props.warningMessage}
         <br />
         <br />
         <span className="text-danger">
           <i className="icon-exclamation icon-fw"></i>
-          {t('admin:v5_page_migration.migration_note')}
+          {props.supplymentaryMessage}
         </span>
       </ModalBody>
       <ModalFooter>
@@ -53,7 +57,7 @@ export const V5PageMigrationModal: FC<V5PageMigrationModalProps> = (props: V5Pag
           className="btn btn-outline-primary ml-3"
           onClick={onConfirm}
         >
-          {t('admin:v5_page_migration.start_upgrading')}
+          {props.confirmButtonTitle ?? t('Confirm')}
         </button>
       </ModalFooter>
     </Modal>

+ 35 - 12
packages/app/src/components/Admin/App/MaintenanceMode.tsx

@@ -1,12 +1,13 @@
 import React, { FC, useState, useCallback } from 'react';
 import { useTranslation } from 'react-i18next';
+
 import loggerFactory from '~/utils/logger';
 
 import { withUnstatedContainers } from '../../UnstatedUtils';
+import { ConfirmModal } from './ConfirmModal';
 import { toastSuccess, toastError } from '~/client/util/apiNotification';
 
 import AdminAppContainer from '~/client/services/AdminAppContainer';
-import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 
 const logger = loggerFactory('growi:maintenanceMode');
 
@@ -18,9 +19,15 @@ const MaintenanceMode: FC<Props> = (props: Props) => {
   const { t } = useTranslation();
   const { adminAppContainer } = props;
 
-  const [isMaintenanceMode, setMaintenanceMode] = useState<boolean | undefined>(undefined);
+  const [isModalOpen, setModalOpen] = useState<boolean>(false);
+  const [isMaintenanceMode, setMaintenanceMode] = useState<boolean | undefined>(adminAppContainer.state.isMaintenanceMode);
+
+  const openModal = () => { setModalOpen(true) };
+  const closeModal = () => { setModalOpen(false) };
+
+  const onConfirmHandler = useCallback(async() => {
+    closeModal();
 
-  const onClickHandler = useCallback(async(e) => {
     try {
       if (isMaintenanceMode) {
         await adminAppContainer.endMaintenanceMode();
@@ -32,21 +39,37 @@ const MaintenanceMode: FC<Props> = (props: Props) => {
       }
     }
     catch (err) {
-      toastError(isMaintenanceMode ? t('failed_to_end_maintenance_mode') : t('failed_to_start_maintenance_mode'));
+      toastError(isMaintenanceMode ? t('maintenance_mode.failed_to_end_maintenance_mode') : t('maintenance_mode.failed_to_start_maintenance_mode'));
     }
 
-    toastSuccess(isMaintenanceMode ? t('successfully_ended_maintenance_mode') : t('successfully_started_maintenance_mode'));
-  }, [isMaintenanceMode, adminAppContainer]);
+    toastSuccess(isMaintenanceMode ? t('maintenance_mode.successfully_ended_maintenance_mode') : t('maintenance_mode.successfully_started_maintenance_mode'));
+  }, [isMaintenanceMode, adminAppContainer, closeModal]);
 
   return (
     <>
-      <p>
-        description. description. description. description. description.
+      <ConfirmModal
+        isModalOpen={isModalOpen}
+        warningMessage={t('admin:maintenance_mode.warning_message')}
+        supplymentaryMessage={t('admin:maintenance_mode.supplymentary_message')}
+        confirmButtonTitle={isMaintenanceMode ? t('maintenance_mode.end_maintenance_mode') : t('maintenance_mode.start_maintenance_mode')}
+        onConfirm={onConfirmHandler}
+        onCancel={() => closeModal()}
+      />
+      <p className="card well">
+        {t('admin:maintenance_mode.description')}
+        <br />
+        <br />
+        <span className="text-warning">
+          <i className="icon-exclamation icon-fw"></i>
+          {t('admin:maintenance_mode.supplymentary_message')}
+        </span>
       </p>
-      <div>
-        <button type="button" onClick={onClickHandler}>
-          {isMaintenanceMode ? t('end_maintenance_mode') : t('start_maintenance_mode')}
-        </button>
+      <div className="row my-3">
+        <div className="mx-auto">
+          <button type="button" className="btn btn-success" onClick={() => openModal()}>
+            {isMaintenanceMode ? t('maintenance_mode.end_maintenance_mode') : t('maintenance_mode.start_maintenance_mode')}
+          </button>
+        </div>
       </div>
     </>
   );

+ 5 - 2
packages/app/src/components/Admin/App/V5PageMigration.tsx

@@ -1,6 +1,6 @@
 import React, { FC, useState } from 'react';
 import { useTranslation } from 'react-i18next';
-import { V5PageMigrationModal } from './V5PageMigrationModal';
+import { ConfirmModal } from './ConfirmModal';
 import AdminAppContainer from '../../../client/services/AdminAppContainer';
 import { withUnstatedContainers } from '../../UnstatedUtils';
 import { toastSuccess, toastError } from '../../../client/util/apiNotification';
@@ -31,8 +31,11 @@ const V5PageMigration: FC<Props> = (props: Props) => {
 
   return (
     <>
-      <V5PageMigrationModal
+      <ConfirmModal
         isModalOpen={isV5PageMigrationModalShown}
+        warningMessage={t('admin:v5_page_migration.modal_migration_warning')}
+        supplymentaryMessage={t('admin:v5_page_migration.migration_note')}
+        confirmButtonTitle={t('admin:v5_page_migration.start_upgrading')}
         onConfirm={onConfirm}
         onCancel={() => setIsV5PageMigrationModalShown(false)}
       />

+ 3 - 0
packages/app/src/server/routes/apiv3/app-settings.js

@@ -265,6 +265,7 @@ module.exports = (crowi) => {
       envGcsUploadNamespace: crowi.configManager.getConfigFromEnvVars('crowi', 'gcs:uploadNamespace'),
 
       isEnabledPlugins: crowi.configManager.getConfig('crowi', 'plugin:isEnabledPlugins'),
+      isMaintenanceMode: crowi.configManager.getConfig('crowi', 'app:isMaintenanceMode'),
     };
     return res.apiv3({ appSettingsParams });
 
@@ -739,6 +740,8 @@ module.exports = (crowi) => {
         res.apiv3Err(new ErrorV3('Failed to end maintenance mode', 'failed_to_end_maintenance_mode'), 500);
       }
     }
+
+    res.apiv3({ flag });
   });
 
   return router;