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

use textInput state to get input text in pagePathHeader component

WNomunomu 2 лет назад
Родитель
Сommit
bad3c60382

+ 6 - 0
apps/app/src/components/Common/ClosableTextInput.tsx

@@ -12,6 +12,7 @@ type ClosableTextInputProps = {
   validationTarget?: string,
   onPressEnter?(inputText: string | null): void
   onClickOutside?(): void
+  handleInputChange?: (string) => void
 }
 
 const ClosableTextInput: FC<ClosableTextInputProps> = memo((props: ClosableTextInputProps) => {
@@ -38,6 +39,11 @@ const ClosableTextInput: FC<ClosableTextInputProps> = memo((props: ClosableTextI
     createValidation(inputText);
     setInputText(inputText);
     setIsAbleToShowAlert(true);
+
+    if (props.handleInputChange != null) {
+      props.handleInputChange(inputText);
+    }
+
   };
 
   const onFocusHandler = async(e: React.ChangeEvent<HTMLInputElement>) => {

+ 1 - 1
apps/app/src/components/PageEditor/PageEditor.tsx

@@ -565,7 +565,7 @@ export const PageEditor = React.memo((props: Props): JSX.Element => {
 
   return (
     <div data-testid="page-editor" id="page-editor" className={`flex-expand-vert ${props.visibility ? '' : 'd-none'}`}>
-      <div className="flex-expand-vert justify-content-center align-items-center pull-left" style={{ minHeight: '72px' }}>
+      <div className="flex-expand-vert justify-content-center" style={{ minHeight: '72px' }}>
         <PageHeader />
       </div>
       <div className={`flex-expand-horiz ${props.visibility ? '' : 'd-none'}`}>

+ 16 - 6
apps/app/src/components/PageHeader/PagePathHeader.tsx

@@ -9,7 +9,7 @@ import { PagePathNav } from '../Common/PagePathNav';
 import { PageSelectModal } from '../PageSelectModal/PageSelectModal';
 
 import { TextInputForPageTitleAndPath } from './TextInputForPageTitleAndPath';
-
+import { usePagePathSubmitHandler } from './page-header-utils';
 
 type Props = {
   currentPagePath: string
@@ -21,9 +21,11 @@ export const PagePathHeader: FC<Props> = (props) => {
 
   const [isRenameInputShown, setRenameInputShown] = useState(false);
   const [isButtonsShown, setButtonShown] = useState(false);
+  const [inputText, setInputText] = useState('');
 
   const { data: editorMode } = useEditorMode();
   const { data: PageSelectModalData, open: openPageSelectModal } = usePageSelectModal();
+  const pagePathSubmitHandler = usePagePathSubmitHandler(currentPage, currentPagePath, setRenameInputShown);
 
   const stateHandler = { isRenameInputShown, setRenameInputShown };
 
@@ -46,21 +48,29 @@ export const PagePathHeader: FC<Props> = (props) => {
     );
   }, [currentPage._id, currentPagePath, isEditorMode]);
 
+  const handleInputChange = (inputText: string) => {
+    setInputText(inputText);
+  };
+
+  console.log(inputText);
+
   return (
     <>
-      <div className="container">
+      <div onMouseLeave={() => setButtonShown(false)}>
         <div
           className="row"
-          onMouseEnter={() => setButtonShown(true)}
-          onMouseLeave={() => setButtonShown(false)}
         >
-          <div className="col-4">
+          <div
+            className="col-4"
+            onMouseEnter={() => setButtonShown(true)}
+          >
             <TextInputForPageTitleAndPath
               currentPagePath={currentPagePath}
               currentPage={currentPage}
               stateHandler={stateHandler}
               inputValue={currentPagePath}
               CustomComponent={PagePath}
+              handleInputChange={handleInputChange}
             />
           </div>
           { isButtonsShown
@@ -69,7 +79,7 @@ export const PagePathHeader: FC<Props> = (props) => {
               <div className="col-4">
                 {
                   isRenameInputShown
-                    ? <button type="button" onClick={() => setRenameInputShown(false)}>完了ボタン</button>
+                    ? <button type="button" onClick={() => console.log('完了!')}>完了ボタン</button>
                     : <button type="button" onClick={() => setRenameInputShown(true)}>編集ボタン</button>
                 }
               </div>

+ 19 - 62
apps/app/src/components/PageHeader/TextInputForPageTitleAndPath.tsx

@@ -1,83 +1,39 @@
-import { FC, useCallback } from 'react';
+import { FC } from 'react';
+import type { Dispatch, SetStateAction } from 'react';
 
-import nodePath from 'path';
-
-import { pathUtils } from '@growi/core/dist/utils';
+import type { IPagePopulatedToShowRevision } from '@growi/core';
 import { useTranslation } from 'next-i18next';
 
-import { apiv3Put } from '~/client/util/apiv3-client';
 import { ValidationTarget } from '~/client/util/input-validator';
-import { toastSuccess, toastError } from '~/client/util/toastr';
-import { useSWRMUTxCurrentPage } from '~/stores/page';
-import { mutatePageTree, mutatePageList } from '~/stores/page-listing';
-import { mutateSearching } from '~/stores/search';
 
 import ClosableTextInput from '../Common/ClosableTextInput';
 
+import { usePagePathSubmitHandler } from './page-header-utils';
+
+type StateHandler = {
+  isRenameInputShown: boolean
+  setRenameInputShown: Dispatch<SetStateAction<boolean>>
+}
 
 type Props = {
-  currentPagePath
-  currentPage
-  stateHandler
-  inputValue
-  CustomComponent
+  currentPagePath: string
+  currentPage: IPagePopulatedToShowRevision
+  stateHandler: StateHandler
+  inputValue: string
+  CustomComponent: () => JSX.Element
+  handleInputChange?: (string) => void
 }
 
 export const TextInputForPageTitleAndPath: FC<Props> = (props) => {
   const {
-    currentPagePath, currentPage, stateHandler, inputValue, CustomComponent,
+    currentPagePath, currentPage, stateHandler, inputValue, CustomComponent, handleInputChange,
   } = props;
 
   const { t } = useTranslation();
 
-  const { trigger: mutateCurrentPage } = useSWRMUTxCurrentPage();
-
   const { isRenameInputShown, setRenameInputShown } = stateHandler;
 
-  const page = currentPage;
-
-  const onRenamed = useCallback((fromPath: string | undefined, toPath: string) => {
-    mutatePageTree();
-    mutateSearching();
-    mutatePageList();
-
-    if (currentPagePath === fromPath || currentPagePath === toPath) {
-      mutateCurrentPage();
-    }
-  }, [currentPagePath, mutateCurrentPage]);
-
-  if (currentPage == null) {
-    return <></>;
-  }
-
-  const onPressEnterForRenameHandler = async(inputText: string) => {
-    const parentPath = pathUtils.addTrailingSlash(nodePath.dirname(page.path ?? ''));
-    const newPagePath = nodePath.resolve(parentPath, inputText);
-
-    if (newPagePath === page.path) {
-      setRenameInputShown(false);
-      return;
-    }
-
-    try {
-      setRenameInputShown(false);
-      await apiv3Put('/pages/rename', {
-        pageId: page._id,
-        revisionId: page.revision._id,
-        newPagePath,
-      });
-
-      if (onRenamed != null) {
-        onRenamed(page.path, newPagePath);
-      }
-
-      toastSuccess(t('renamed_pages', { path: page.path }));
-    }
-    catch (err) {
-      setRenameInputShown(true);
-      toastError(err);
-    }
-  };
+  const pagePathSubmitHandler = usePagePathSubmitHandler(currentPage, currentPagePath, setRenameInputShown);
 
   return (
     <>
@@ -87,8 +43,9 @@ export const TextInputForPageTitleAndPath: FC<Props> = (props) => {
             value={inputValue}
             placeholder={t('Input page name')}
             onClickOutside={() => { setRenameInputShown(false) }}
-            onPressEnter={onPressEnterForRenameHandler}
+            onPressEnter={pagePathSubmitHandler}
             validationTarget={ValidationTarget.PAGE}
+            handleInputChange={handleInputChange}
           />
         </div>
       ) : (

+ 63 - 0
apps/app/src/components/PageHeader/page-header-utils.ts

@@ -0,0 +1,63 @@
+import type { Dispatch, SetStateAction } from 'react';
+
+import nodePath from 'path';
+
+import type { IPagePopulatedToShowRevision } from '@growi/core';
+import { pathUtils } from '@growi/core/dist/utils';
+import { useTranslation } from 'next-i18next';
+
+import { apiv3Put } from '~/client/util/apiv3-client';
+import { toastSuccess, toastError } from '~/client/util/toastr';
+import { useSWRMUTxCurrentPage } from '~/stores/page';
+import { mutatePageTree, mutatePageList } from '~/stores/page-listing';
+import { mutateSearching } from '~/stores/search';
+
+export const usePagePathSubmitHandler = (
+    currentPage: IPagePopulatedToShowRevision, currentPagePath: string, setRenameInputShown: Dispatch<SetStateAction<boolean>>,
+): (inputText: string) => Promise<void> => {
+
+  const { trigger: mutateCurrentPage } = useSWRMUTxCurrentPage();
+  const { t } = useTranslation();
+
+  const onRenamed = (fromPath: string | undefined, toPath: string) => {
+    mutatePageTree();
+    mutateSearching();
+    mutatePageList();
+
+    if (currentPagePath === fromPath || currentPagePath === toPath) {
+      mutateCurrentPage();
+    }
+  };
+
+  const pagePathSubmitHandler = async(inputText: string) => {
+
+    const parentPath = pathUtils.addTrailingSlash(nodePath.dirname(currentPage.path ?? ''));
+    const newPagePath = nodePath.resolve(parentPath, inputText);
+
+    if (newPagePath === currentPage.path) {
+      setRenameInputShown(false);
+      return;
+    }
+
+    try {
+      setRenameInputShown(false);
+      await apiv3Put('/pages/rename', {
+        pageId: currentPage._id,
+        revisionId: currentPage.revision._id,
+        newPagePath,
+      });
+
+      if (onRenamed != null) {
+        onRenamed(currentPage.path, newPagePath);
+      }
+
+      toastSuccess(t('renamed_pages', { path: currentPage.path }));
+    }
+    catch (err) {
+      setRenameInputShown(true);
+      toastError(err);
+    }
+  };
+
+  return pagePathSubmitHandler;
+};