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

Merge branch 'master' into feat/90732-add-dropdown-to-select-parent

Shun Miyazawa 4 лет назад
Родитель
Сommit
a7ba3a4ff0

+ 22 - 3
packages/app/src/components/PageCreateModal.jsx

@@ -1,8 +1,11 @@
 
 
-import React, { useEffect, useState } from 'react';
+import React, {
+  useEffect, useState, useMemo,
+} from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
 import { Modal, ModalHeader, ModalBody } from 'reactstrap';
 import { Modal, ModalHeader, ModalBody } from 'reactstrap';
+import { debounce } from 'throttle-debounce';
 
 
 import { withTranslation } from 'react-i18next';
 import { withTranslation } from 'react-i18next';
 import { format } from 'date-fns';
 import { format } from 'date-fns';
@@ -19,7 +22,7 @@ import { usePageCreateModal } from '~/stores/modal';
 import PagePathAutoComplete from './PagePathAutoComplete';
 import PagePathAutoComplete from './PagePathAutoComplete';
 
 
 const {
 const {
-  userPageRoot, isCreatablePage, generateEditorPath,
+  userPageRoot, isCreatablePage, generateEditorPath, isUsersHomePage,
 } = pagePathUtils;
 } = pagePathUtils;
 
 
 const PageCreateModal = (props) => {
 const PageCreateModal = (props) => {
@@ -39,12 +42,25 @@ const PageCreateModal = (props) => {
   const [todayInput2, setTodayInput2] = useState('');
   const [todayInput2, setTodayInput2] = useState('');
   const [pageNameInput, setPageNameInput] = useState(pageNameInputInitialValue);
   const [pageNameInput, setPageNameInput] = useState(pageNameInputInitialValue);
   const [template, setTemplate] = useState(null);
   const [template, setTemplate] = useState(null);
+  const [isMatchedWithUserHomePagePath, setIsMatchedWithUserHomePagePath] = useState(false);
 
 
   // ensure pageNameInput is synced with selectedPagePath || currentPagePath
   // ensure pageNameInput is synced with selectedPagePath || currentPagePath
   useEffect(() => {
   useEffect(() => {
     setPageNameInput(isCreatablePage(pathname) ? pathUtils.addTrailingSlash(pathname) : '/');
     setPageNameInput(isCreatablePage(pathname) ? pathUtils.addTrailingSlash(pathname) : '/');
   }, [pathname]);
   }, [pathname]);
 
 
+  const checkIsUsersHomePageDebounce = useMemo(() => {
+    const checkIsUsersHomePage = () => {
+      setIsMatchedWithUserHomePagePath(isUsersHomePage(pageNameInput));
+    };
+
+    return debounce(1000, checkIsUsersHomePage);
+  }, [pageNameInput]);
+
+  useEffect(() => {
+    checkIsUsersHomePageDebounce(pageNameInput);
+  }, [checkIsUsersHomePageDebounce, pageNameInput]);
+
   function transitBySubmitEvent(e, transitHandler) {
   function transitBySubmitEvent(e, transitHandler) {
     // prevent page transition by submit
     // prevent page transition by submit
     e.preventDefault();
     e.preventDefault();
@@ -189,7 +205,6 @@ const PageCreateModal = (props) => {
           <h3 className="grw-modal-head pb-2">{t('Create under')}</h3>
           <h3 className="grw-modal-head pb-2">{t('Create under')}</h3>
 
 
           <div className="d-sm-flex align-items-center justify-items-between">
           <div className="d-sm-flex align-items-center justify-items-between">
-
             <div className="flex-fill">
             <div className="flex-fill">
               {isReachable
               {isReachable
                 ? (
                 ? (
@@ -221,12 +236,16 @@ const PageCreateModal = (props) => {
                 data-testid="btn-create-page-under-below"
                 data-testid="btn-create-page-under-below"
                 className="grw-btn-create-page btn btn-outline-primary rounded-pill text-nowrap ml-3"
                 className="grw-btn-create-page btn btn-outline-primary rounded-pill text-nowrap ml-3"
                 onClick={createInputPage}
                 onClick={createInputPage}
+                disabled={isMatchedWithUserHomePagePath}
               >
               >
                 <i className="icon-fw icon-doc"></i>{t('Create')}
                 <i className="icon-fw icon-doc"></i>{t('Create')}
               </button>
               </button>
             </div>
             </div>
 
 
           </div>
           </div>
+          { isMatchedWithUserHomePagePath && (
+            <p className="text-danger mt-2">Error: Cannot create page under /user page directory.</p>
+          ) }
 
 
         </fieldset>
         </fieldset>
       </div>
       </div>

+ 3 - 2
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -353,8 +353,6 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
         createFromPageTree: true,
         createFromPageTree: true,
       });
       });
 
 
-      setCreating(false);
-
       mutateChildren();
       mutateChildren();
 
 
       if (!hasDescendants) {
       if (!hasDescendants) {
@@ -366,6 +364,9 @@ const Item: FC<ItemProps> = (props: ItemProps) => {
     catch (err) {
     catch (err) {
       toastError(err);
       toastError(err);
     }
     }
+    finally {
+      setCreating(false);
+    }
   };
   };
 
 
   const inputValidator = (title: string | null): AlertInfo | null => {
   const inputValidator = (title: string | null): AlertInfo | null => {

+ 1 - 1
packages/app/src/server/routes/page.js

@@ -1262,7 +1262,7 @@ module.exports = function(crowi, app) {
     }
     }
     catch (err) {
     catch (err) {
       logger.error('Error occured while get setting', err);
       logger.error('Error occured while get setting', err);
-      return res.json(ApiResponse.error('Failed to revert deleted page.'));
+      return res.json(ApiResponse.error(err));
     }
     }
 
 
     const result = {};
     const result = {};