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

Merge pull request #8273 from weseek/feat/135443-move-page-create-logic

feat: Move page create hooks
Ryoji Shimizu 2 лет назад
Родитель
Сommit
4bda08809a

+ 49 - 0
apps/app/src/client/services/use-on-template-button-clicked.ts

@@ -0,0 +1,49 @@
+import { useCallback, useState } from 'react';
+
+import { useRouter } from 'next/router';
+
+import { createPage, exist } from '~/client/services/page-operation';
+import { LabelType } from '~/interfaces/template';
+
+export const useOnTemplateButtonClicked = (
+    currentPagePath?: string,
+): {
+  onClickHandler: (label: LabelType) => Promise<void>,
+  isPageCreating: boolean
+} => {
+  const router = useRouter();
+  const [isPageCreating, setIsPageCreating] = useState(false);
+
+  const onClickHandler = useCallback(async(label: LabelType) => {
+    try {
+      setIsPageCreating(true);
+
+      const path = currentPagePath == null || currentPagePath === '/'
+        ? `/${label}`
+        : `${currentPagePath}/${label}`;
+
+      const params = {
+        isSlackEnabled: false,
+        slackChannels: '',
+        grant: 4,
+      // grant: currentPage?.grant || 1,
+      // grantUserGroupId: currentPage?.grantedGroup?._id,
+      };
+
+      const res = await exist(JSON.stringify([path]));
+      if (!res.pages[path]) {
+        await createPage(path, '', params);
+      }
+
+      router.push(`${path}#edit`);
+    }
+    catch (err) {
+      throw err;
+    }
+    finally {
+      setIsPageCreating(false);
+    }
+  }, [currentPagePath, router]);
+
+  return { onClickHandler, isPageCreating };
+};

+ 13 - 3
apps/app/src/components/CreateTemplateModal.tsx

@@ -1,12 +1,13 @@
-import React from 'react';
+import React, { useCallback } from 'react';
 
 import { pathUtils } from '@growi/core/dist/utils';
 import { useTranslation } from 'next-i18next';
 import { Modal, ModalHeader, ModalBody } from 'reactstrap';
 
+import { useOnTemplateButtonClicked } from '~/client/services/use-on-template-button-clicked';
+import { toastError } from '~/client/util/toastr';
 import { TargetType, LabelType } from '~/interfaces/template';
 
-import { useOnTemplateButtonClicked } from './Navbar/hooks';
 
 type TemplateCardProps = {
   target: TargetType;
@@ -56,6 +57,15 @@ export const CreateTemplateModal: React.FC<CreateTemplateModalProps> = ({
 
   const { onClickHandler: onClickTemplateButton, isPageCreating } = useOnTemplateButtonClicked(path);
 
+  const onClickTemplateButtonHandler = useCallback(async(label: LabelType) => {
+    try {
+      await onClickTemplateButton(label);
+    }
+    catch (err) {
+      toastError(err);
+    }
+  }, [onClickTemplateButton]);
+
   const parentPath = pathUtils.addTrailingSlash(path);
 
   const renderTemplateCard = (target: TargetType, label: LabelType) => (
@@ -64,7 +74,7 @@ export const CreateTemplateModal: React.FC<CreateTemplateModalProps> = ({
         target={target}
         label={label}
         isPageCreating={isPageCreating}
-        onClickHandler={() => onClickTemplateButton(label)}
+        onClickHandler={() => onClickTemplateButtonHandler(label)}
       />
     </div>
   );

+ 2 - 47
apps/app/src/components/Navbar/hooks.tsx

@@ -1,11 +1,10 @@
-import { useCallback, useState } from 'react';
+import { useCallback } from 'react';
 
 import { useTranslation } from 'next-i18next';
 import { useRouter } from 'next/router';
 
-import { createPage, exist } from '~/client/services/page-operation';
+import { createPage } from '~/client/services/page-operation';
 import { toastError } from '~/client/util/toastr';
-import { LabelType } from '~/interfaces/template';
 import { useIsNotFound } from '~/stores/page';
 import { EditorMode, useEditorMode } from '~/stores/ui';
 import loggerFactory from '~/utils/logger';
@@ -57,47 +56,3 @@ export const useOnPageEditorModeButtonClicked = (
     mutateEditorMode(editorMode);
   }, [isNotFound, mutateEditorMode, path, router, setIsCreating, t]);
 };
-
-export const useOnTemplateButtonClicked = (
-    currentPagePath: string,
-): {
-  onClickHandler: (label: LabelType) => Promise<void>,
-  isPageCreating: boolean
-} => {
-  const router = useRouter();
-  const [isPageCreating, setIsPageCreating] = useState(false);
-
-  const onClickHandler = useCallback(async(label: LabelType) => {
-    try {
-      setIsPageCreating(true);
-
-      const path = currentPagePath == null || currentPagePath === '/'
-        ? `/${label}`
-        : `${currentPagePath}/${label}`;
-
-      const params = {
-        isSlackEnabled: false,
-        slackChannels: '',
-        grant: 4,
-        // grant: currentPage?.grant || 1,
-        // grantUserGroupId: currentPage?.grantedGroup?._id,
-      };
-
-      const res = await exist(JSON.stringify([path]));
-      if (!res.pages[path]) {
-        await createPage(path, '', params);
-      }
-
-      router.push(`${path}#edit`);
-    }
-    catch (err) {
-      logger.warn(err);
-      toastError(err);
-    }
-    finally {
-      setIsPageCreating(false);
-    }
-  }, [currentPagePath, router]);
-
-  return { onClickHandler, isPageCreating };
-};

+ 6 - 6
apps/app/src/components/Sidebar/PageCreateButton/DropendMenu.tsx

@@ -2,12 +2,13 @@ import React from 'react';
 
 import { useTranslation } from 'react-i18next';
 
+import { LabelType } from '~/interfaces/template';
+
 type DropendMenuProps = {
   todaysPath: string,
   onClickCreateNewPageButtonHandler: () => Promise<void>
   onClickCreateTodaysButtonHandler: () => Promise<void>
-  onClickTemplateForChildrenButtonHandler: () => Promise<void>
-  onClickTemplateForDescendantsButtonHandler: () => Promise<void>
+  onClickTemplateButtonHandler: (label: LabelType) => Promise<void>
 }
 
 export const DropendMenu = React.memo((props: DropendMenuProps): JSX.Element => {
@@ -15,8 +16,7 @@ export const DropendMenu = React.memo((props: DropendMenuProps): JSX.Element =>
     todaysPath,
     onClickCreateNewPageButtonHandler,
     onClickCreateTodaysButtonHandler,
-    onClickTemplateForChildrenButtonHandler,
-    onClickTemplateForDescendantsButtonHandler,
+    onClickTemplateButtonHandler,
   } = props;
 
   const { t } = useTranslation('commons');
@@ -48,7 +48,7 @@ export const DropendMenu = React.memo((props: DropendMenuProps): JSX.Element =>
       <li>
         <button
           className="dropdown-item"
-          onClick={onClickTemplateForChildrenButtonHandler}
+          onClick={() => onClickTemplateButtonHandler('_template')}
           type="button"
         >
           {t('create_page_dropdown.template.children')}
@@ -57,7 +57,7 @@ export const DropendMenu = React.memo((props: DropendMenuProps): JSX.Element =>
       <li>
         <button
           className="dropdown-item"
-          onClick={onClickTemplateForDescendantsButtonHandler}
+          onClick={() => onClickTemplateButtonHandler('__template')}
           type="button"
         >
           {t('create_page_dropdown.template.descendants')}

+ 21 - 145
apps/app/src/components/Sidebar/PageCreateButton/PageCreateButton.tsx

@@ -1,172 +1,49 @@
-import React, { useCallback, useState } from 'react';
+import React, { useState, useCallback } from 'react';
 
 import { pagePathUtils } from '@growi/core/dist/utils';
 import { format } from 'date-fns';
-import { useRouter } from 'next/router';
 
-import { createPage, exist } from '~/client/services/page-operation';
+import { useOnTemplateButtonClicked } from '~/client/services/use-on-template-button-clicked';
 import { toastError } from '~/client/util/toastr';
+import { LabelType } from '~/interfaces/template';
 import { useCurrentUser } from '~/stores/context';
 import { useSWRxCurrentPage } from '~/stores/page';
-import loggerFactory from '~/utils/logger';
 
 import { CreateButton } from './CreateButton';
 import { DropendMenu } from './DropendMenu';
 import { DropendToggle } from './DropendToggle';
-
-const logger = loggerFactory('growi:cli:PageCreateButton');
+import { useOnNewButtonClicked, useOnTodaysButtonClicked } from './hooks';
 
 export const PageCreateButton = React.memo((): JSX.Element => {
-  const router = useRouter();
   const { data: currentPage, isLoading } = useSWRxCurrentPage();
   const { data: currentUser } = useCurrentUser();
 
   const [isHovered, setIsHovered] = useState(false);
-  const [isCreating, setIsCreating] = useState(false);
 
   const now = format(new Date(), 'yyyy/MM/dd');
   const userHomepagePath = pagePathUtils.userHomepagePath(currentUser);
   const todaysPath = `${userHomepagePath}/memo/${now}`;
 
-  const onMouseEnterHandler = () => {
-    setIsHovered(true);
-  };
-
-  const onMouseLeaveHandler = () => {
-    setIsHovered(false);
-  };
-
-  const onClickCreateNewPageButtonHandler = useCallback(async() => {
-    if (isLoading) return;
-
-    try {
-      setIsCreating(true);
-
-      const parentPath = currentPage == null
-        ? '/'
-        : currentPage.path;
-
-      const params = {
-        isSlackEnabled: false,
-        slackChannels: '',
-        grant: 4,
-        // grant: currentPage?.grant || 1,
-        // grantUserGroupId: currentPage?.grantedGroup?._id,
-        shouldGeneratePath: true,
-      };
-
-      const response = await createPage(parentPath, '', params);
-
-      router.push(`${response.page.id}#edit`);
-    }
-    catch (err) {
-      logger.warn(err);
-      toastError(err);
-    }
-    finally {
-      setIsCreating(false);
-    }
-  }, [currentPage, isLoading, router]);
-
-  const onClickCreateTodaysButtonHandler = useCallback(async() => {
-    if (currentUser == null) {
-      return;
-    }
-
-    try {
-      setIsCreating(true);
-
-      // TODO: get grant, grantUserGroupId data from parent page
-      // https://redmine.weseek.co.jp/issues/133892
-      const params = {
-        isSlackEnabled: false,
-        slackChannels: '',
-        grant: 4,
-      };
-
-      const res = await exist(JSON.stringify([todaysPath]));
-      if (!res.pages[todaysPath]) {
-        await createPage(todaysPath, '', params);
-      }
-
-      router.push(`${todaysPath}#edit`);
-    }
-    catch (err) {
-      logger.warn(err);
-      toastError(err);
-    }
-    finally {
-      setIsCreating(false);
-    }
-  }, [currentUser, router, todaysPath]);
-
-  const onClickTemplateForChildrenButtonHandler = useCallback(async() => {
-    if (isLoading) return;
+  const { onClickHandler: onClickNewButton, isPageCreating: isNewPageCreating } = useOnNewButtonClicked(isLoading, currentPage);
+  const { onClickHandler: onClickTodaysButton, isPageCreating: isTodaysPageCreating } = useOnTodaysButtonClicked(todaysPath, currentUser);
+  const { onClickHandler: onClickTemplateButton, isPageCreating: isTemplatePageCreating } = useOnTemplateButtonClicked(currentPage?.path);
 
+  const onClickTemplateButtonHandler = useCallback(async(label: LabelType) => {
     try {
-      setIsCreating(true);
-
-      const path = currentPage == null || currentPage.path === '/'
-        ? '/_template'
-        : `${currentPage.path}/_template`;
-
-      const params = {
-        isSlackEnabled: false,
-        slackChannels: '',
-        grant: 4,
-        // grant: currentPage?.grant || 1,
-        // grantUserGroupId: currentPage?.grantedGroup?._id,
-      };
-
-      const res = await exist(JSON.stringify([path]));
-      if (!res.pages[path]) {
-        await createPage(path, '', params);
-      }
-
-      router.push(`${path}#edit`);
+      await onClickTemplateButton(label);
     }
     catch (err) {
-      logger.warn(err);
       toastError(err);
     }
-    finally {
-      setIsCreating(false);
-    }
-  }, [currentPage, isLoading, router]);
-
-  const onClickTemplateForDescendantsButtonHandler = useCallback(async() => {
-    if (isLoading) return;
-
-    try {
-      setIsCreating(true);
+  }, [onClickTemplateButton]);
 
-      const path = currentPage == null || currentPage.path === '/'
-        ? '/__template'
-        : `${currentPage.path}/__template`;
-
-      const params = {
-        isSlackEnabled: false,
-        slackChannels: '',
-        grant: 4,
-        // grant: currentPage?.grant || 1,
-        // grantUserGroupId: currentPage?.grantedGroup?._id,
-      };
-
-      const res = await exist(JSON.stringify([path]));
-      if (!res.pages[path]) {
-        await createPage(path, '', params);
-      }
+  const onMouseEnterHandler = () => {
+    setIsHovered(true);
+  };
 
-      router.push(`${path}#edit`);
-    }
-    catch (err) {
-      logger.warn(err);
-      toastError(err);
-    }
-    finally {
-      setIsCreating(false);
-    }
-  }, [currentPage, isLoading, router]);
+  const onMouseLeaveHandler = () => {
+    setIsHovered(false);
+  };
 
   return (
     <div
@@ -177,8 +54,8 @@ export const PageCreateButton = React.memo((): JSX.Element => {
       <div className="btn-group flex-grow-1">
         <CreateButton
           className="z-2"
-          onClick={onClickCreateNewPageButtonHandler}
-          disabled={isCreating}
+          onClick={onClickNewButton}
+          disabled={isNewPageCreating || isTodaysPageCreating || isTemplatePageCreating}
         />
       </div>
       { isHovered && (
@@ -190,10 +67,9 @@ export const PageCreateButton = React.memo((): JSX.Element => {
           />
           <DropendMenu
             todaysPath={todaysPath}
-            onClickCreateNewPageButtonHandler={onClickCreateNewPageButtonHandler}
-            onClickCreateTodaysButtonHandler={onClickCreateTodaysButtonHandler}
-            onClickTemplateForChildrenButtonHandler={onClickTemplateForChildrenButtonHandler}
-            onClickTemplateForDescendantsButtonHandler={onClickTemplateForDescendantsButtonHandler}
+            onClickCreateNewPageButtonHandler={onClickNewButton}
+            onClickCreateTodaysButtonHandler={onClickTodaysButton}
+            onClickTemplateButtonHandler={onClickTemplateButtonHandler}
           />
         </div>
       )}

+ 95 - 0
apps/app/src/components/Sidebar/PageCreateButton/hooks.tsx

@@ -0,0 +1,95 @@
+import { useCallback, useState } from 'react';
+
+import type { Nullable, IPagePopulatedToShowRevision, IUserHasId } from '@growi/core';
+import { useRouter } from 'next/router';
+
+import { createPage, exist } from '~/client/services/page-operation';
+import { toastError } from '~/client/util/toastr';
+
+export const useOnNewButtonClicked = (
+    isLoading: boolean,
+    currentPage?: IPagePopulatedToShowRevision | null,
+): {
+  onClickHandler: () => Promise<void>,
+  isPageCreating: boolean
+} => {
+  const router = useRouter();
+  const [isPageCreating, setIsPageCreating] = useState(false);
+
+  const onClickHandler = useCallback(async() => {
+    if (isLoading) return;
+
+    try {
+      setIsPageCreating(true);
+
+      const parentPath = currentPage == null
+        ? '/'
+        : currentPage.path;
+
+      const params = {
+        isSlackEnabled: false,
+        slackChannels: '',
+        grant: 4,
+        // grant: currentPage?.grant || 1,
+        // grantUserGroupId: currentPage?.grantedGroup?._id,
+        shouldGeneratePath: true,
+      };
+
+      const response = await createPage(parentPath, '', params);
+
+      router.push(`${response.page.id}#edit`);
+    }
+    catch (err) {
+      toastError(err);
+    }
+    finally {
+      setIsPageCreating(false);
+    }
+  }, [currentPage, isLoading, router]);
+
+  return { onClickHandler, isPageCreating };
+};
+
+export const useOnTodaysButtonClicked = (
+    todaysPath: string,
+    currentUser?: Nullable<IUserHasId> | undefined,
+): {
+  onClickHandler: () => Promise<void>,
+  isPageCreating: boolean
+} => {
+  const router = useRouter();
+  const [isPageCreating, setIsPageCreating] = useState(false);
+
+  const onClickHandler = useCallback(async() => {
+    if (currentUser == null) {
+      return;
+    }
+
+    try {
+      setIsPageCreating(true);
+
+      // TODO: get grant, grantUserGroupId data from parent page
+      // https://redmine.weseek.co.jp/issues/133892
+      const params = {
+        isSlackEnabled: false,
+        slackChannels: '',
+        grant: 4,
+      };
+
+      const res = await exist(JSON.stringify([todaysPath]));
+      if (!res.pages[todaysPath]) {
+        await createPage(todaysPath, '', params);
+      }
+
+      router.push(`${todaysPath}#edit`);
+    }
+    catch (err) {
+      toastError(err);
+    }
+    finally {
+      setIsPageCreating(false);
+    }
+  }, [currentUser, router, todaysPath]);
+
+  return { onClickHandler, isPageCreating };
+};