Procházet zdrojové kódy

create custom hooks

ryoji-s před 2 roky
rodič
revize
80c6a0155f

+ 5 - 44
apps/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -12,8 +12,6 @@ import { useRouter } from 'next/router';
 import { DropdownItem } from 'reactstrap';
 
 import { exportAsMarkdown, updateContentWidth } from '~/client/services/page-operation';
-import { apiv3Post } from '~/client/util/apiv3-client';
-import { toastError } from '~/client/util/toastr';
 import type { OnDuplicatedFunction, OnRenamedFunction, OnDeletedFunction } from '~/interfaces/ui';
 import {
   useCurrentPathname,
@@ -24,16 +22,14 @@ import {
   usePageDuplicateModal, usePageRenameModal, usePageDeleteModal, usePagePresentationModal,
 } from '~/stores/modal';
 import {
-  useSWRMUTxCurrentPage, useCurrentPageId, useSWRxPageInfo, useIsNotFound,
+  useSWRMUTxCurrentPage, useCurrentPageId, useSWRxPageInfo,
 } from '~/stores/page';
 import { mutatePageTree } from '~/stores/page-listing';
 import {
   useEditorMode, useIsAbleToShowPageManagement,
   useIsAbleToChangeEditorMode,
   useSelectedGrant,
-  EditorMode,
 } from '~/stores/ui';
-import loggerFactory from '~/utils/logger';
 
 import CreateTemplateModal from '../CreateTemplateModal';
 import AttachmentIcon from '../Icons/AttachmentIcon';
@@ -43,11 +39,11 @@ import ShareLinkIcon from '../Icons/ShareLinkIcon';
 import { NotAvailable } from '../NotAvailable';
 import { Skeleton } from '../Skeleton';
 
+import { useOnPageEditorModeButtonClicked } from './hooks';
+
 import styles from './GrowiContextualSubNavigation.module.scss';
 import PageEditorModeManagerStyles from './PageEditorModeManager.module.scss';
 
-const logger = loggerFactory('growi:Navbar:GrowiContextualSubNavigation');
-
 const PageEditorModeManager = dynamic(
   () => import('./PageEditorModeManager').then(mod => mod.PageEditorModeManager),
   { ssr: false, loading: () => <Skeleton additionalClass={`${PageEditorModeManagerStyles['grw-page-editor-mode-manager-skeleton']}`} /> },
@@ -186,7 +182,6 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
   const { currentPage } = props;
 
   const router = useRouter();
-  const { t } = useTranslation('commons');
 
   const { data: shareLinkId } = useShareLinkId();
   const { trigger: mutateCurrentPage } = useSWRMUTxCurrentPage();
@@ -197,14 +192,13 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
   const revision = currentPage?.revision;
   const revisionId = (revision != null && isPopulated(revision)) ? revision._id : undefined;
 
-  const { data: editorMode, mutate: mutateEditorMode } = useEditorMode();
+  const { data: editorMode } = useEditorMode();
   const { data: pageId } = useCurrentPageId();
   const { data: currentUser } = useCurrentUser();
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isReadOnlyUser } = useIsReadOnlyUser();
   const { data: isSharedUser } = useIsSharedUser();
   const { data: isContainerFluid } = useIsContainerFluid();
-  const { data: isNotFound } = useIsNotFound();
   const { data: grantData } = useSelectedGrant();
 
   const { data: isAbleToShowPageManagement } = useIsAbleToShowPageManagement();
@@ -248,6 +242,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
 
   const { isLinkSharingDisabled } = props;
 
+  const onPageEditorModeButtonClicked = useOnPageEditorModeButtonClicked(setIsCreating, path, grant, grantUserGroupId);
 
   // TODO: implement tags for editor
   // refs: https://redmine.weseek.co.jp/issues/132125
@@ -257,40 +252,6 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
   //   return;
   // }, [mutatePageTagsForEditors]);
 
-  const onPageEditorModeButtonClicked = useCallback(async(viewType: EditorMode) => {
-    if (isNotFound == null || path == null || grant == null) {
-      return;
-    }
-
-    if (isNotFound) {
-      try {
-        setIsCreating(true);
-
-        const response = await apiv3Post('/pages/', {
-          path,
-          body: undefined,
-          grant,
-          grantUserGroupId,
-          isSlackEnabled: false,
-          slackChannels: '',
-          pageTags: [],
-        });
-
-        // Should not mutateEditorMode as it might prevent transitioning during mutation
-        router.push(`${response.data.page.id}#edit`);
-      }
-      catch (err) {
-        logger.warn(err);
-        toastError(t('toaster.create_failed', { target: path }));
-      }
-      finally {
-        setIsCreating(false);
-      }
-    }
-
-    mutateEditorMode(viewType);
-  }, [grant, grantUserGroupId, isNotFound, mutateEditorMode, path, router, t]);
-
   const duplicateItemClickedHandler = useCallback(async(page: IPageForPageDuplicateModal) => {
     const duplicatedHandler: OnDuplicatedFunction = (fromPath, toPath) => {
       router.push(toPath);

+ 2 - 2
apps/app/src/components/Navbar/PageEditorModeManager.tsx

@@ -58,11 +58,11 @@ export const PageEditorModeManager = (props: Props): JSX.Element => {
   const { data: isDeviceSmallerThanMd } = useIsDeviceSmallerThanMd();
 
   const pageEditorModeButtonClickedHandler = useCallback((viewType: EditorMode) => {
-    if (isBtnDisabled || onPageEditorModeButtonClicked == null) {
+    if (isBtnDisabled) {
       return;
     }
 
-    onPageEditorModeButtonClicked(viewType);
+    onPageEditorModeButtonClicked?.(viewType);
   }, [isBtnDisabled, onPageEditorModeButtonClicked]);
 
   return (

+ 58 - 0
apps/app/src/components/Navbar/hooks.tsx

@@ -0,0 +1,58 @@
+import { useCallback } from 'react';
+
+import { useTranslation } from 'next-i18next';
+import { useRouter } from 'next/router';
+
+import { apiv3Post } from '~/client/util/apiv3-client';
+import { toastError } from '~/client/util/toastr';
+import { useIsNotFound } from '~/stores/page';
+import { EditorMode, useEditorMode } from '~/stores/ui';
+import loggerFactory from '~/utils/logger';
+
+const logger = loggerFactory('growi:Navbar:GrowiContextualSubNavigation');
+
+export const useOnPageEditorModeButtonClicked = (
+    setIsCreating:React.Dispatch<React.SetStateAction<boolean>>,
+    path?: string,
+    grant?: number,
+    grantUserGroupId?: string,
+): (editorMode: EditorMode) => Promise<void> => {
+  const router = useRouter();
+  const { t } = useTranslation('commons');
+  const { data: isNotFound } = useIsNotFound();
+  const { mutate: mutateEditorMode } = useEditorMode();
+
+  return useCallback(async(editorMode: EditorMode) => {
+    if (isNotFound == null || path == null || grant == null) {
+      return;
+    }
+
+    if (isNotFound) {
+      try {
+        setIsCreating(true);
+
+        const response = await apiv3Post('/pages/', {
+          path,
+          body: undefined,
+          grant,
+          grantUserGroupId,
+          isSlackEnabled: false,
+          slackChannels: '',
+          pageTags: [],
+        });
+
+        // Should not mutateEditorMode as it might prevent transitioning during mutation
+        router.push(`${response.data.page.id}#edit`);
+      }
+      catch (err) {
+        logger.warn(err);
+        toastError(t('toaster.create_failed', { target: path }));
+      }
+      finally {
+        setIsCreating(false);
+      }
+    }
+
+    mutateEditorMode(editorMode);
+  }, [grant, grantUserGroupId, isNotFound, mutateEditorMode, path, router, setIsCreating, t]);
+};