Przeglądaj źródła

Store onConflict() in usePageStatusAlert in case of conflict

Shun Miyazawa 2 lat temu
rodzic
commit
aa7a77dc19

+ 27 - 0
apps/app/src/client/services/update-page/conflict.ts

@@ -1,4 +1,6 @@
 import type { ErrorV3 } from '@growi/core/dist/models';
+import { useSWRStatic } from '@growi/core/dist/swr';
+import type { SWRResponse } from 'swr';
 
 import { PageUpdateErrorCode } from '~/interfaces/apiv3';
 import { type RemoteRevisionData } from '~/stores/remote-latest-page';
@@ -20,3 +22,28 @@ export const extractRemoteRevisionDataFromErrorObj = (errors: Array<ErrorV3>): R
     }
   }
 };
+
+/*
+* PageStatusAlert
+*/
+type PageStatusAlertStatus = {
+  onConflict?: () => void,
+}
+
+type PageStatusAlertUtils = {
+  storeMethods: (conflictHandler: () => void) => void,
+  clearMethods: () => void,
+}
+export const usePageStatusAlert = (): SWRResponse<PageStatusAlertStatus, Error> & PageStatusAlertUtils => {
+  const swrResponse = useSWRStatic<PageStatusAlertStatus, Error>('pageStatusAlert', undefined);
+
+  return {
+    ...swrResponse,
+    storeMethods(onConflict) {
+      swrResponse.mutate({ onConflict });
+    },
+    clearMethods() {
+      swrResponse.mutate({});
+    },
+  };
+};

+ 12 - 8
apps/app/src/components/PageEditor/PageEditor.tsx

@@ -20,7 +20,7 @@ import { throttle, debounce } from 'throttle-debounce';
 
 import { useShouldExpandContent } from '~/client/services/layout';
 import { useUpdateStateAfterSave } from '~/client/services/page-operation';
-import { updatePage, extractRemoteRevisionDataFromErrorObj } from '~/client/services/update-page';
+import { updatePage, extractRemoteRevisionDataFromErrorObj, usePageStatusAlert } from '~/client/services/update-page';
 import { apiv3Get, apiv3PostForm } from '~/client/util/apiv3-client';
 import { toastError, toastSuccess, toastWarning } from '~/client/util/toastr';
 import { SocketEventName } from '~/interfaces/websocket';
@@ -121,7 +121,8 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
   const { data: currentIndentSize, mutate: mutateCurrentIndentSize } = useCurrentIndentSize();
   const { data: defaultIndentSize } = useDefaultIndentSize();
   const { data: acceptedUploadFileType } = useAcceptedUploadFileType();
-  const { data: conflictDiffModalStatus, open: openConflictDiffModal, close: closeConflictDiffModal } = useConflictDiffModal();
+  const { open: openConflictDiffModal, close: closeConflictDiffModal } = useConflictDiffModal();
+  const { storeMethods: storeConflictHandler, clearMethods: clearConflictHandler } = usePageStatusAlert();
   const { data: editorSettings } = useEditorSettings();
   const { setRemoteLatestPageData } = useSetRemoteLatestPageData();
   const { data: user } = useCurrentUser();
@@ -226,8 +227,6 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
       // to sync revision id with page tree: https://github.com/weseek/growi/pull/7227
       mutatePageTree();
 
-      closeConflictDiffModal();
-
       return page;
     }
     catch (error) {
@@ -246,7 +245,7 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
     finally {
       mutateWaitingSaveProcessing(false);
     }
-  }, [pageId, grantData, mutateWaitingSaveProcessing, closeConflictDiffModal, t]);
+  }, [pageId, grantData, mutateWaitingSaveProcessing, t]);
 
   const generateResolveConflictHandler = useCallback((revisionId: string, saveOptions?: SaveOptions, onConflict?: ConflictHandler) => {
     return async(newMarkdown: string) => {
@@ -258,19 +257,24 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
       // Reflect conflict resolution results in CodeMirrorEditor
       codeMirrorEditor?.initDoc(newMarkdown);
 
+      clearConflictHandler();
+      closeConflictDiffModal();
       toastSuccess(t('toaster.save_succeeded'));
       updateStateAfterSave?.();
     };
-  }, [codeMirrorEditor, save, t, updateStateAfterSave]);
+  }, [clearConflictHandler, closeConflictDiffModal, codeMirrorEditor, save, t, updateStateAfterSave]);
 
   const onConflictHandler: ConflictHandler = useCallback((remoteRevidsionData, newMarkdown, saveOptions) => {
     setRemoteLatestPageData(remoteRevidsionData);
 
     const resolveConflictHandler = generateResolveConflictHandler(remoteRevidsionData.remoteRevisionId, saveOptions, onConflictHandler);
 
-    openConflictDiffModal(newMarkdown, resolveConflictHandler);
+    const conflicthandler = () => {
+      openConflictDiffModal(newMarkdown, resolveConflictHandler);
+    };
 
-  }, [generateResolveConflictHandler, openConflictDiffModal, setRemoteLatestPageData]);
+    storeConflictHandler(conflicthandler);
+  }, [generateResolveConflictHandler, openConflictDiffModal, setRemoteLatestPageData, storeConflictHandler]);
 
   const saveAndReturnToViewHandler = useCallback(async(opts: {slackChannels: string, overwriteScopesOfDescendants?: boolean}) => {
     const markdown = codeMirrorEditor?.getDoc();