itizawa 5 лет назад
Родитель
Сommit
841fb1f500

+ 5 - 4
src/client/js/components/EmptyTrashModal.jsx

@@ -10,23 +10,24 @@ import { withUnstatedContainers } from './UnstatedUtils';
 
 import AppContainer from '../services/AppContainer';
 import ApiErrorMessage from './PageManagement/ApiErrorMessage';
+import ApiErrorMessageWrapper from './PageManagement/ApiErrorMessageWrapper';
 
 const EmptyTrashModal = (props) => {
   const {
     t, isOpen, onClose, appContainer,
   } = props;
 
-  const [errForDisplay, setErrForDisplay] = useState(null);
+  const [errs, setErrs] = useState(null);
 
   async function emptyTrash() {
-    setErrForDisplay(null);
+    setErrs(null);
 
     try {
       await appContainer.apiv3Delete('/pages/empty-trash');
       window.location.reload();
     }
     catch (err) {
-      setErrForDisplay(err);
+      setErrs(err);
     }
   }
 
@@ -43,7 +44,7 @@ const EmptyTrashModal = (props) => {
         { t('modal_empty.notice')}
       </ModalBody>
       <ModalFooter>
-        <ApiErrorMessage errForDisplay={errForDisplay} />
+        <ApiErrorMessageWrapper errs={errs} />
         <button type="button" className="btn btn-danger" onClick={emptyButtonHandler}>
           <i className="icon-trash mr-2" aria-hidden="true"></i> Empty
         </button>

+ 5 - 4
src/client/js/components/PageDeleteModal.jsx

@@ -11,6 +11,7 @@ import { withUnstatedContainers } from './UnstatedUtils';
 import PageContainer from '../services/PageContainer';
 
 import ApiErrorMessage from './PageManagement/ApiErrorMessage';
+import ApiErrorMessageWrapper from './PageManagement/ApiErrorMessageWrapper';
 
 const deleteIconAndKey = {
   completely: {
@@ -33,7 +34,7 @@ const PageDeleteModal = (props) => {
   const [isDeleteCompletely, setIsDeleteCompletely] = useState(isDeleteCompletelyModal && isAbleToDeleteCompletely);
   const deleteMode = isDeleteCompletely ? 'completely' : 'temporary';
 
-  const [errForDisplay, setErrForDisplay] = useState(null);
+  const [errs, setErrs] = useState(null);
 
   function changeIsDeleteRecursivelyHandler() {
     setIsDeleteRecursively(!isDeleteRecursively);
@@ -47,7 +48,7 @@ const PageDeleteModal = (props) => {
   }
 
   async function deletePage() {
-    setErrForDisplay(null);
+    setErrs(null);
 
     try {
       const response = await pageContainer.deletePage(isDeleteRecursively, isDeleteCompletely);
@@ -55,7 +56,7 @@ const PageDeleteModal = (props) => {
       window.location.href = encodeURI(trashPagePath);
     }
     catch (err) {
-      setErrForDisplay(err);
+      setErrs(err);
     }
   }
 
@@ -122,7 +123,7 @@ const PageDeleteModal = (props) => {
         {!isDeleteCompletelyModal && renderDeleteCompletelyForm()}
       </ModalBody>
       <ModalFooter>
-        <ApiErrorMessage errForDisplay={errForDisplay} />
+        <ApiErrorMessageWrapper errs={errs} />
         <button type="button" className={`btn btn-${deleteIconAndKey[deleteMode].color}`} onClick={deleteButtonHandler}>
           <i className={`icon-${deleteIconAndKey[deleteMode].icon}`} aria-hidden="true"></i>
           { t(`modal_delete.delete_${deleteIconAndKey[deleteMode].translationKey}`) }

+ 5 - 5
src/client/js/components/PageDuplicateModal.jsx

@@ -12,7 +12,7 @@ import { withUnstatedContainers } from './UnstatedUtils';
 import AppContainer from '../services/AppContainer';
 import PageContainer from '../services/PageContainer';
 import PagePathAutoComplete from './PagePathAutoComplete';
-import ApiErrorMessage from './PageManagement/ApiErrorMessage';
+import ApiErrorMessageWrapper from './PageManagement/ApiErrorMessageWrapper';
 
 const PageDuplicateModal = (props) => {
   const { t, appContainer, pageContainer } = props;
@@ -24,7 +24,7 @@ const PageDuplicateModal = (props) => {
 
   const [pageNameInput, setPageNameInput] = useState(path);
 
-  const [errForDisplay, setErrForDisplay] = useState(null);
+  const [errs, setErrs] = useState(null);
 
   const [subordinatedPaths, setSubordinatedPaths] = useState([]);
   const [getSubordinatedError, setGetSuborinatedError] = useState(null);
@@ -68,7 +68,7 @@ const PageDuplicateModal = (props) => {
   }, [props.isOpen, getSubordinatedList]);
 
   async function duplicate() {
-    setErrForDisplay(null);
+    setErrs(null);
 
     try {
       const res = await appContainer.apiPost('/pages.duplicate', { page_id: pageId, new_path: pageNameInput });
@@ -76,7 +76,7 @@ const PageDuplicateModal = (props) => {
       window.location.href = encodeURI(`${page.path}?duplicated=${path}`);
     }
     catch (err) {
-      setErrForDisplay(err);
+      setErrs(err);
     }
   }
 
@@ -141,7 +141,7 @@ const PageDuplicateModal = (props) => {
         </div>
       </ModalBody>
       <ModalFooter>
-        <ApiErrorMessage errForDisplay={errForDisplay} targetPath={pageNameInput} />
+        <ApiErrorMessageWrapper errs={errs} targetPath={pageNameInput} />
         <button type="button" className="btn btn-primary" onClick={duplicate}>Duplicate page</button>
       </ModalFooter>
     </Modal>

+ 53 - 64
src/client/js/components/PageManagement/ApiErrorMessage.jsx

@@ -2,90 +2,79 @@ import React from 'react';
 import PropTypes from 'prop-types';
 
 import { withTranslation } from 'react-i18next';
-import toArrayIfNot from '../../../../lib/util/toArrayIfNot';
 
 const ApiErrorMessage = (props) => {
   const {
-    t, errForDisplay, targetPath,
+    t, errorCode, errorMessage, targetPath,
   } = props;
 
   function reload() {
     window.location.reload();
   }
 
-  if (errForDisplay == null) {
-    return null;
-  }
-
-  const errArray = toArrayIfNot(errForDisplay);
-
-  function renderMessage(err) {
-
-    function renderMessageByErrorCode() {
-      switch (err.code) {
-        case 'already_exists':
-          return (
-            <>
-              <strong><i className="icon-fw icon-ban"></i>{ t('page_api_error.already_exists') }</strong>
-              <small><a href={targetPath}>{targetPath} <i className="icon-login"></i></a></small>
-            </>
-          );
-        case 'notfound_or_forbidden':
-          return (
-            <strong><i className="icon-fw icon-ban"></i>{ t('page_api_error.notfound_or_forbidden') }</strong>
-          );
-        case 'user_not_admin':
-          return (
-            <strong><i className="icon-fw icon-ban"></i>{ t('page_api_error.user_not_admin') }</strong>
-          );
-        case 'outdated':
-          return (
-            <>
-              <strong><i className="icon-fw icon-bulb"></i> { t('page_api_error.outdated') }</strong>
-              <a className="btn-link" onClick={reload}>
-                <i className="fa fa-angle-double-right"></i> { t('Load latest') }
-              </a>
-            </>
-          );
-        case 'invalid_path':
-          return (
-            <strong><i className="icon-fw icon-ban"></i> Invalid path</strong>
-          );
-        default:
-          return (
-            <strong><i className="icon-fw icon-ban"></i> Unknown error occured</strong>
-          );
-      }
-    }
-
-    if (err.code != null) {
-      return renderMessageByErrorCode();
+  function renderMessageByErrorCode() {
+    switch (errorCode) {
+      case 'already_exists':
+        return (
+          <>
+            <strong><i className="icon-fw icon-ban"></i>{ t('page_api_error.already_exists') }</strong>
+            <small><a href={targetPath}>{targetPath} <i className="icon-login"></i></a></small>
+          </>
+        );
+      case 'notfound_or_forbidden':
+        return (
+          <strong><i className="icon-fw icon-ban"></i>{ t('page_api_error.notfound_or_forbidden') }</strong>
+        );
+      case 'user_not_admin':
+        return (
+          <strong><i className="icon-fw icon-ban"></i>{ t('page_api_error.user_not_admin') }</strong>
+        );
+      case 'outdated':
+        return (
+          <>
+            <strong><i className="icon-fw icon-bulb"></i> { t('page_api_error.outdated') }</strong>
+            <a className="btn-link" onClick={reload}>
+              <i className="fa fa-angle-double-right"></i> { t('Load latest') }
+            </a>
+          </>
+        );
+      case 'invalid_path':
+        return (
+          <strong><i className="icon-fw icon-ban"></i> Invalid path</strong>
+        );
+      default:
+        return (
+          <strong><i className="icon-fw icon-ban"></i> Unknown error occured</strong>
+        );
     }
+  }
 
-    if (err.message != null) {
-      return err.message;
-    }
+  if (errorCode != null) {
+    return (
+      <span className="text-danger">
+        {renderMessageByErrorCode()}
+      </span>
+    );
+  }
 
+  if (errorMessage != null) {
+    return (
+      <span className="text-danger">
+        {errorMessage}
+      </span>
+    );
   }
 
-  return (
-    <>
-      {errArray.map((error) => {
-        return (
-          <span key={error.message} className="text-danger">
-            {renderMessage(error)}
-          </span>
-        );
-      })}
-    </>
-  );
+  // render null if no error has occurred
+  return null;
 
 };
 
 ApiErrorMessage.propTypes = {
   t:            PropTypes.func.isRequired, //  i18next
 
-  errForDisplay:       PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
+  errorCode:    PropTypes.string,
+  errorMessage: PropTypes.string,
   targetPath:   PropTypes.string,
 };
 

+ 25 - 0
src/client/js/components/PageManagement/ApiErrorMessageWrapper.jsx

@@ -0,0 +1,25 @@
+
+
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import ApiErrorMessage from './ApiErrorMessage';
+import toArrayIfNot from '../../../../lib/util/toArrayIfNot';
+
+function ApiErrorMessageWrapper(props) {
+  const errs = toArrayIfNot(props.errs);
+
+  return (
+    <>
+      {errs.map(err => <ApiErrorMessage key={err.code} errorCode={err.code} errorMessage={err.message} targetPath={props.targetPath} />)}
+    </>
+  );
+
+}
+
+ApiErrorMessageWrapper.propTypes = {
+  errs:         PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
+  targetPath:   PropTypes.string,
+};
+
+export default ApiErrorMessageWrapper;

+ 5 - 4
src/client/js/components/PageRenameModal.jsx

@@ -12,6 +12,7 @@ import { withUnstatedContainers } from './UnstatedUtils';
 import AppContainer from '../services/AppContainer';
 import PageContainer from '../services/PageContainer';
 import ApiErrorMessage from './PageManagement/ApiErrorMessage';
+import ApiErrorMessageWrapper from './PageManagement/ApiErrorMessageWrapper';
 
 const PageRenameModal = (props) => {
   const {
@@ -24,7 +25,7 @@ const PageRenameModal = (props) => {
 
   const [pageNameInput, setPageNameInput] = useState(path);
 
-  const [errForDisplay, setErrForDisplay] = useState(null);
+  const [errs, setErrs] = useState(null);
 
   const [isRenameRecursively, SetIsRenameRecursively] = useState(true);
   const [isRenameRedirect, SetIsRenameRedirect] = useState(false);
@@ -51,7 +52,7 @@ const PageRenameModal = (props) => {
   }
 
   async function rename() {
-    setErrForDisplay(null);
+    setErrs(null);
 
     try {
       const response = await pageContainer.rename(
@@ -71,7 +72,7 @@ const PageRenameModal = (props) => {
       window.location.href = `${url.pathname}${url.search}`;
     }
     catch (err) {
-      setErrForDisplay(err);
+      setErrs(err);
     }
   }
 
@@ -148,7 +149,7 @@ const PageRenameModal = (props) => {
         </div>
       </ModalBody>
       <ModalFooter>
-        <ApiErrorMessage errForDisplay={errForDisplay} targetPath={pageNameInput} />
+        <ApiErrorMessageWrapper errs={errs} targetPath={pageNameInput} />
         <button type="button" className="btn btn-primary" onClick={rename}>Rename</button>
       </ModalFooter>
     </Modal>

+ 5 - 4
src/client/js/components/PutbackPageModal.jsx

@@ -12,13 +12,14 @@ import { withUnstatedContainers } from './UnstatedUtils';
 import PageContainer from '../services/PageContainer';
 
 import ApiErrorMessage from './PageManagement/ApiErrorMessage';
+import ApiErrorMessageWrapper from './PageManagement/ApiErrorMessageWrapper';
 
 const PutBackPageModal = (props) => {
   const {
     t, isOpen, onClose, pageContainer, path,
   } = props;
 
-  const [errForDisplay, setErrForDisplay] = useState(null);
+  const [errs, setErrs] = useState(null);
 
   const [isPutbackRecursively, setIsPutbackRecursively] = useState(true);
 
@@ -27,7 +28,7 @@ const PutBackPageModal = (props) => {
   }
 
   async function putbackPage() {
-    setErrForDisplay(null);
+    setErrs(null);
 
     try {
       const response = await pageContainer.revertRemove(isPutbackRecursively);
@@ -35,7 +36,7 @@ const PutBackPageModal = (props) => {
       window.location.href = encodeURI(putbackPagePath);
     }
     catch (err) {
-      setErrForDisplay(err);
+      setErrs(err);
     }
   }
 
@@ -70,7 +71,7 @@ const PutBackPageModal = (props) => {
         </div>
       </ModalBody>
       <ModalFooter>
-        <ApiErrorMessage errForDisplay={errForDisplay} />
+        <ApiErrorMessageWrapper errs={errs} />
         <button type="button" className="btn btn-info" onClick={putbackPageButtonHandler}>
           <i className="icon-action-undo mr-2" aria-hidden="true"></i> { t('Put Back') }
         </button>