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

Merge branch 'master' into fix/sharelink-page

ryoji-s 3 лет назад
Родитель
Сommit
fcb6fbc6c9

+ 2 - 1
packages/app/public/static/locales/en_US/translation.json

@@ -540,7 +540,8 @@
     "issue_share_link": "Succeeded to issue new share link",
     "remove_share_link": "Succeeded to remove {{count}} share links",
     "switch_disable_link_sharing_success": "Succeeded to update share link setting",
-    "failed_to_reset_password":"Failed to reset password"
+    "failed_to_reset_password":"Failed to reset password",
+    "save_succeeded": "Saved successfully"
   },
   "template": {
     "modal_label": {

+ 2 - 1
packages/app/public/static/locales/ja_JP/translation.json

@@ -531,7 +531,8 @@
     "issue_share_link": "共有リンクを作成しました",
     "remove_share_link": "共有リンクを{{count}}件削除しました",
     "switch_disable_link_sharing_success": "共有リンクの設定を変更しました",
-    "failed_to_reset_password":"パスワードのリセットに失敗しました"
+    "failed_to_reset_password":"パスワードのリセットに失敗しました",
+    "save_succeeded": "保存に成功しました"
   },
   "template": {
     "modal_label": {

+ 2 - 1
packages/app/public/static/locales/zh_CN/translation.json

@@ -510,7 +510,8 @@
 		"remove_user_success": "Succeeded to removing {{username}} ",
     "remove_external_user_success": "Succeeded to remove {{accountId}} ",
     "switch_disable_link_sharing_success": "成功更新分享链接设置",
-    "failed_to_reset_password":"Failed to reset password"
+    "failed_to_reset_password":"Failed to reset password",
+    "save_succeeded": "已成功保存"
   },
 	"template": {
 		"modal_label": {

+ 8 - 5
packages/app/src/components/Page.tsx

@@ -10,6 +10,7 @@ import dynamic from 'next/dynamic';
 
 import { HtmlElementNode } from 'rehype-toc';
 
+import { toastSuccess, toastError } from '~/client/util/apiNotification';
 import { getOptionsToSave } from '~/client/util/editor';
 import {
   useIsGuestUser, useCurrentPageTocNode, useShareLinkId,
@@ -124,11 +125,12 @@ class PageSubstance extends React.Component<PageSubstanceProps> {
     //   const { page, tags } = await pageContainer.save(newMarkdown, this.props.editorMode, optionsToSave);
     //   logger.debug('success to save');
 
-    //   pageContainer.showSuccessToastr();
+    // // Todo: add translation
+    // toastSuccess(t(''));
     // }
     // catch (error) {
     //   logger.error('failed to save', error);
-    //   pageContainer.showErrorToastr(error);
+    // toastError(error);
     // }
     // finally {
     //   this.setState({ currentTargetTableArea: null });
@@ -156,11 +158,12 @@ class PageSubstance extends React.Component<PageSubstanceProps> {
     //     const { page, tags } = await pageContainer.save(newMarkdown, this.props.editorMode, optionsToSave);
     //     logger.debug('success to save');
 
-  //     pageContainer.showSuccessToastr();
-  //   }
+    // // Todo: add translation
+    //   toastSuccess(t(''));
+    //   }
   //   catch (error) {
   //     logger.error('failed to save', error);
-  //     pageContainer.showErrorToastr(error);
+  //     toastError(error);
   //   }
   //   finally {
   //     this.setState({ currentTargetDrawioArea: null });

+ 14 - 7
packages/app/src/components/PageEditor.tsx

@@ -6,9 +6,11 @@ import EventEmitter from 'events';
 
 import { envUtils, PageGrant } from '@growi/core';
 import detectIndent from 'detect-indent';
+import { useTranslation } from 'next-i18next';
 import { throttle, debounce } from 'throttle-debounce';
 
 import { saveOrUpdate } from '~/client/services/page-operation';
+import { toastSuccess, toastError } from '~/client/util/apiNotification';
 import { apiGet, apiPostForm } from '~/client/util/apiv1-client';
 import { getOptionsToSave } from '~/client/util/editor';
 import { IEditorMethods } from '~/interfaces/editor-methods';
@@ -48,6 +50,7 @@ let isOriginOfScrollSyncPreview = false;
 
 const PageEditor = React.memo((): JSX.Element => {
 
+  const { t } = useTranslation();
   const { data: pageId } = useCurrentPageId();
   const { data: currentPagePath } = useCurrentPagePath();
   const { data: currentPathname } = useCurrentPathname();
@@ -95,7 +98,8 @@ const PageEditor = React.memo((): JSX.Element => {
     setMarkdownWithDebounce(value, isClean);
   }, [setMarkdownWithDebounce]);
 
-  const save = useCallback(async(opts?: {overwriteScopesOfDescendants: boolean}) => {
+  // return true if the save succeeds, otherwise false.
+  const save = useCallback(async(opts?: {overwriteScopesOfDescendants: boolean}): Promise<boolean> => {
     if (grantData == null || isSlackEnabled == null || currentPathname == null) {
       logger.error('Some materials to save are invalid', { grantData, isSlackEnabled, currentPathname });
       throw new Error('Some materials to save are invalid');
@@ -113,10 +117,11 @@ const PageEditor = React.memo((): JSX.Element => {
       await saveOrUpdate(optionsToSave, { pageId, path: currentPagePath || currentPathname, revisionId: currentRevisionId }, markdownToSave.current);
       await mutateCurrentPage();
       mutateIsEnabledUnsavedWarning(false);
+      return true;
     }
     catch (error) {
       logger.error('failed to save', error);
-      // pageContainer.showErrorToastr(error);
+      toastError(error);
       if (error.code === 'conflict') {
         // pageContainer.setState({
         //   remoteRevisionId: error.data.revisionId,
@@ -125,6 +130,7 @@ const PageEditor = React.memo((): JSX.Element => {
         //   lastUpdateUser: error.data.user,
         // });
       }
+      return false;
     }
 
   // eslint-disable-next-line max-len
@@ -144,11 +150,12 @@ const PageEditor = React.memo((): JSX.Element => {
       return;
     }
 
-    await save();
+    const isSuccess = await save();
+    if (isSuccess) {
+      toastSuccess(t('toaster.save_succeeded'));
+    }
 
-    // TODO: show toastr
-    // pageContainer.showErrorToastr(error);
-  }, [editorMode, save]);
+  }, [editorMode, save, t]);
 
 
   /**
@@ -201,7 +208,7 @@ const PageEditor = React.memo((): JSX.Element => {
     }
     catch (e) {
       logger.error('failed to upload', e);
-      // pageContainer.showErrorToastr(e);
+      toastError(e);
     }
     finally {
       editorRef.current.terminateUploadingState();