Browse Source

Implementation of child element creation function

WNomunomu 2 years ago
parent
commit
941f73262b

+ 2 - 2
apps/app/src/components/Sidebar/PageTree/ItemsTree.tsx

@@ -30,7 +30,7 @@ import PageTreeContentSkeleton from '../Skeleton/PageTreeContentSkeleton';
 
 import Item from './Item';
 import { ItemNode } from './ItemNode';
-import { CreatePageTreeItem } from './PageTreeItem';
+import { PageTreeItem } from './PageTreeItem';
 import SimpleItem from './SimpleItem';
 
 import styles from './ItemsTree.module.scss';
@@ -272,7 +272,7 @@ const ItemsTree = (props: ItemsTreeProps): JSX.Element => {
     initialItemNode = generateInitialNodeBeforeResponse(targetAndAncestorsData.targetAndAncestors);
   }
 
-  const PageTreeItem = CreatePageTreeItem();
+  // const PageTreeItem = CreatePageTreeItem();
 
   if (initialItemNode != null) {
     return (

+ 309 - 153
apps/app/src/components/Sidebar/PageTree/PageTreeItem.tsx

@@ -1,5 +1,5 @@
 import React, {
-  useCallback, useState, FC, useEffect, ReactNode, useMemo,
+  useCallback, useState, FC, useEffect, ReactNode, useMemo, useRef, createContext, useContext,
 } from 'react';
 
 import nodePath from 'path';
@@ -42,7 +42,183 @@ import SimpleItem from './SimpleItem';
 const logger = loggerFactory('growi:cli:Item');
 
 
-export const CreatePageTreeItem = () => {
+// export const CreatePageTreeItem = () => {
+//   const getNewPathAfterMoved = (droppedPagePath: string, newParentPagePath: string): string => {
+//     const pageTitle = nodePath.basename(droppedPagePath);
+//     return nodePath.join(newParentPagePath, pageTitle);
+//   };
+
+//   const isDroppable = (fromPage?: Partial<IPageHasId>, newParentPage?: Partial<IPageHasId>, printLog = false): boolean => {
+//     if (fromPage == null || newParentPage == null || fromPage.path == null || newParentPage.path == null) {
+//       if (printLog) {
+//         logger.warn('Any of page, page.path or droppedPage.path is null');
+//       }
+//       return false;
+//     }
+
+//     const newPathAfterMoved = getNewPathAfterMoved(fromPage.path, newParentPage.path);
+//     return pagePathUtils.canMoveByPath(fromPage.path, newPathAfterMoved) && !pagePathUtils.isUsersTopPage(newParentPage.path);
+//   };
+
+//   return function usePageTreeItem(props) {
+//     const { t } = useTranslation();
+//     const router = useRouter();
+
+//     const {
+//       itemNode, targetPathOrId, isOpen: _isOpen = false,
+//       onRenamed, onClickDuplicateMenuItem, onClickDeleteMenuItem, isEnableActions, isReadOnlyUser,
+//     } = props;
+
+//     const { page, children } = itemNode;
+
+//     const [currentChildren, setCurrentChildren] = useState(children);
+//     const [isOpen, setIsOpen] = useState(_isOpen);
+//     const [isNewPageInputShown, setNewPageInputShown] = useState(false);
+//     const [shouldHide, setShouldHide] = useState(false);
+//     const [isRenameInputShown, setRenameInputShown] = useState(false);
+//     const [isCreating, setCreating] = useState(false);
+
+//     const { data, mutate: mutateChildren } = useSWRxPageChildren(isOpen ? page._id : null);
+//     const { trigger: mutateCurrentUserBookmarks } = useSWRMUTxCurrentUserBookmarks();
+//     const { trigger: mutatePageInfo } = useSWRMUTxPageInfo(page._id ?? null);
+
+//     // descendantCount
+//     const { getDescCount } = usePageTreeDescCountMap();
+//     const descendantCount = getDescCount(page._id) || page.descendantCount || 0;
+
+
+//     // hasDescendants flag
+//     const isChildrenLoaded = currentChildren?.length > 0;
+//     const hasDescendants = descendantCount > 0 || isChildrenLoaded;
+
+//     // to re-show hidden item when useDrag end() callback
+//     const displayDroppedItemByPageId = useCallback((pageId) => {
+//       const target = document.getElementById(`pagetree-item-${pageId}`);
+//       if (target == null) {
+//         return;
+//       }
+
+//       //   // wait 500ms to avoid removing before d-none is set by useDrag end() callback
+//       setTimeout(() => {
+//         target.classList.remove('d-none');
+//       }, 500);
+//     }, []);
+
+//     const [, drag] = useDrag({
+//       type: 'PAGE_TREE',
+//       item: { page },
+//       canDrag: () => {
+//         if (page.path == null) {
+//           return false;
+//         }
+//         return !pagePathUtils.isUsersProtectedPages(page.path);
+//       },
+//       end: (item, monitor) => {
+//         // in order to set d-none to dropped Item
+//         const dropResult = monitor.getDropResult();
+//         if (dropResult != null) {
+//           setShouldHide(true);
+//         }
+//       },
+//       collect: monitor => ({
+//         isDragging: monitor.isDragging(),
+//         canDrag: monitor.canDrag(),
+//       }),
+//     });
+
+//     const pageItemDropHandler = async(item: ItemNode) => {
+//       const { page: droppedPage } = item;
+
+//       if (!isDroppable(droppedPage, page, true)) {
+//         return;
+//       }
+
+//       if (droppedPage.path == null || page.path == null) {
+//         return;
+//       }
+
+//       const newPagePath = getNewPathAfterMoved(droppedPage.path, page.path);
+
+//       try {
+//         await apiv3Put('/pages/rename', {
+//           pageId: droppedPage._id,
+//           revisionId: droppedPage.revision,
+//           newPagePath,
+//           isRenameRedirect: false,
+//           updateMetadata: true,
+//         });
+
+//         await mutatePageTree();
+//         await mutateChildren();
+
+//         if (onRenamed != null) {
+//           onRenamed(page.path, newPagePath);
+//         }
+
+//         // force open
+//         setIsOpen(true);
+//       }
+//       catch (err) {
+//         // display the dropped item
+//         displayDroppedItemByPageId(droppedPage._id);
+
+//         if (err.code === 'operation__blocked') {
+//           toastWarning(t('pagetree.you_cannot_move_this_page_now'));
+//         }
+//         else {
+//           toastError(t('pagetree.something_went_wrong_with_moving_page'));
+//         }
+//       }
+//     };
+
+//     const [{ isOver }, drop] = useDrop<ItemNode, Promise<void>, { isOver: boolean }>(
+//       () => ({
+//         accept: 'PAGE_TREE',
+//         drop: pageItemDropHandler,
+//         hover: (item, monitor) => {
+//           // when a drag item is overlapped more than 1 sec, the drop target item will be opened.
+//           if (monitor.isOver()) {
+//             setTimeout(() => {
+//               if (monitor.isOver()) {
+//                 setIsOpen(true);
+//               }
+//             }, 600);
+//           }
+//         },
+//         canDrop: (item) => {
+//           const { page: droppedPage } = item;
+//           return isDroppable(droppedPage, page);
+//         },
+//         collect: monitor => ({
+//           isOver: monitor.isOver(),
+//         }),
+//       }),
+//       [page],
+//     );
+
+//     // const itemRef = (c) => { drag(c); drop(c) };
+
+//     const itemRef = c => drag(c);
+
+
+//     return (
+//       <SimpleItem
+//         key={props.key}
+//         targetPathOrId={props.targetPathOrId}
+//         itemNode={props.itemNode}
+//         isOpen
+//         isEnableActions={props.isEnableActions}
+//         isReadOnlyUser={props.isReadOnlyUser}
+//         onRenamed={props.onRenamed}
+//         onClickDuplicateMenuItem={props.onClickDuplicateMenuItem}
+//         onClickDeleteMenuItem={props.onClickDeleteMenuItem}
+//         isOver={isOver}
+//       />
+//     );
+//   };
+// };
+
+export const PageTreeItem = (props) => {
   const getNewPathAfterMoved = (droppedPagePath: string, newParentPagePath: string): string => {
     const pageTitle = nodePath.basename(droppedPagePath);
     return nodePath.join(newParentPagePath, pageTitle);
@@ -60,162 +236,142 @@ export const CreatePageTreeItem = () => {
     return pagePathUtils.canMoveByPath(fromPage.path, newPathAfterMoved) && !pagePathUtils.isUsersTopPage(newParentPage.path);
   };
 
-  return function usePageTreeItem(props) {
-    const { t } = useTranslation();
-    const router = useRouter();
-
-    const {
-      itemNode, targetPathOrId, isOpen: _isOpen = false,
-      onRenamed, onClickDuplicateMenuItem, onClickDeleteMenuItem, isEnableActions, isReadOnlyUser,
-    } = props;
-
-    const { page, children } = itemNode;
-
-    const [currentChildren, setCurrentChildren] = useState(children);
-    const [isOpen, setIsOpen] = useState(_isOpen);
-    const [isNewPageInputShown, setNewPageInputShown] = useState(false);
-    const [shouldHide, setShouldHide] = useState(false);
-    const [isRenameInputShown, setRenameInputShown] = useState(false);
-    const [isCreating, setCreating] = useState(false);
-
-    const { data, mutate: mutateChildren } = useSWRxPageChildren(isOpen ? page._id : null);
-    const { trigger: mutateCurrentUserBookmarks } = useSWRMUTxCurrentUserBookmarks();
-    const { trigger: mutatePageInfo } = useSWRMUTxPageInfo(page._id ?? null);
-
-    // descendantCount
-    const { getDescCount } = usePageTreeDescCountMap();
-    const descendantCount = getDescCount(page._id) || page.descendantCount || 0;
-
-
-    // hasDescendants flag
-    const isChildrenLoaded = currentChildren?.length > 0;
-    const hasDescendants = descendantCount > 0 || isChildrenLoaded;
-
-    // to re-show hidden item when useDrag end() callback
-    const displayDroppedItemByPageId = useCallback((pageId) => {
-      const target = document.getElementById(`pagetree-item-${pageId}`);
-      if (target == null) {
-        return;
+  const { t } = useTranslation();
+  const router = useRouter();
+  const {
+    itemNode, targetPathOrId, isOpen: _isOpen = false,
+    onRenamed, onClickDuplicateMenuItem, onClickDeleteMenuItem, isEnableActions, isReadOnlyUser,
+  } = props;
+  const { page, children } = itemNode;
+  const [currentChildren, setCurrentChildren] = useState(children);
+  const [isOpen, setIsOpen] = useState(_isOpen);
+  const [isNewPageInputShown, setNewPageInputShown] = useState(false);
+  const [shouldHide, setShouldHide] = useState(false);
+  const [isRenameInputShown, setRenameInputShown] = useState(false);
+  const [isCreating, setCreating] = useState(false);
+  const { data, mutate: mutateChildren } = useSWRxPageChildren(isOpen ? page._id : null);
+  const { trigger: mutateCurrentUserBookmarks } = useSWRMUTxCurrentUserBookmarks();
+  const { trigger: mutatePageInfo } = useSWRMUTxPageInfo(page._id ?? null);
+  // descendantCount
+  const { getDescCount } = usePageTreeDescCountMap();
+  const descendantCount = getDescCount(page._id) || page.descendantCount || 0;
+  // hasDescendants flag
+  const isChildrenLoaded = currentChildren?.length > 0;
+  const hasDescendants = descendantCount > 0 || isChildrenLoaded;
+  // to re-show hidden item when useDrag end() callback
+  const displayDroppedItemByPageId = useCallback((pageId) => {
+    const target = document.getElementById(`pagetree-item-${pageId}`);
+    if (target == null) {
+      return;
+    }
+    //   // wait 500ms to avoid removing before d-none is set by useDrag end() callback
+    setTimeout(() => {
+      target.classList.remove('d-none');
+    }, 500);
+  }, []);
+
+  const [, drag] = useDrag({
+    type: 'PAGE_TREE',
+    item: { page },
+    canDrag: () => {
+      if (page.path == null) {
+        return false;
       }
-
-      //   // wait 500ms to avoid removing before d-none is set by useDrag end() callback
-      setTimeout(() => {
-        target.classList.remove('d-none');
-      }, 500);
-    }, []);
-
-    const [, drag] = useDrag({
-      type: 'PAGE_TREE',
-      item: { page },
-      canDrag: () => {
-        if (page.path == null) {
-          return false;
-        }
-        return !pagePathUtils.isUsersProtectedPages(page.path);
-      },
-      end: (item, monitor) => {
-        // in order to set d-none to dropped Item
-        const dropResult = monitor.getDropResult();
-        if (dropResult != null) {
-          setShouldHide(true);
-        }
-      },
-      collect: monitor => ({
-        isDragging: monitor.isDragging(),
-        canDrag: monitor.canDrag(),
-      }),
-    });
-
-    const pageItemDropHandler = async(item: ItemNode) => {
-      const { page: droppedPage } = item;
-
-      if (!isDroppable(droppedPage, page, true)) {
-        return;
+      return !pagePathUtils.isUsersProtectedPages(page.path);
+    },
+    end: (item, monitor) => {
+      // in order to set d-none to dropped Item
+      const dropResult = monitor.getDropResult();
+      if (dropResult != null) {
+        setShouldHide(true);
       }
-
-      if (droppedPage.path == null || page.path == null) {
-        return;
+    },
+    collect: monitor => ({
+      isDragging: monitor.isDragging(),
+      canDrag: monitor.canDrag(),
+    }),
+  });
+
+  const pageItemDropHandler = async(item: ItemNode) => {
+    const { page: droppedPage } = item;
+    if (!isDroppable(droppedPage, page, true)) {
+      return;
+    }
+    if (droppedPage.path == null || page.path == null) {
+      return;
+    }
+    const newPagePath = getNewPathAfterMoved(droppedPage.path, page.path);
+    try {
+      await apiv3Put('/pages/rename', {
+        pageId: droppedPage._id,
+        revisionId: droppedPage.revision,
+        newPagePath,
+        isRenameRedirect: false,
+        updateMetadata: true,
+      });
+      await mutatePageTree();
+      await mutateChildren();
+      if (onRenamed != null) {
+        onRenamed(page.path, newPagePath);
       }
-
-      const newPagePath = getNewPathAfterMoved(droppedPage.path, page.path);
-
-      try {
-        await apiv3Put('/pages/rename', {
-          pageId: droppedPage._id,
-          revisionId: droppedPage.revision,
-          newPagePath,
-          isRenameRedirect: false,
-          updateMetadata: true,
-        });
-
-        await mutatePageTree();
-        await mutateChildren();
-
-        if (onRenamed != null) {
-          onRenamed(page.path, newPagePath);
-        }
-
-        // force open
-        setIsOpen(true);
+      // force open
+      setIsOpen(true);
+    }
+    catch (err) {
+      // display the dropped item
+      displayDroppedItemByPageId(droppedPage._id);
+      if (err.code === 'operation__blocked') {
+        toastWarning(t('pagetree.you_cannot_move_this_page_now'));
       }
-      catch (err) {
-        // display the dropped item
-        displayDroppedItemByPageId(droppedPage._id);
+      else {
+        toastError(t('pagetree.something_went_wrong_with_moving_page'));
+      }
+    }
+  };
 
-        if (err.code === 'operation__blocked') {
-          toastWarning(t('pagetree.you_cannot_move_this_page_now'));
+  const [{ isOver }, drop] = useDrop<ItemNode, Promise<void>, { isOver: boolean }>(
+    () => ({
+      accept: 'PAGE_TREE',
+      drop: pageItemDropHandler,
+      hover: (item, monitor) => {
+        // when a drag item is overlapped more than 1 sec, the drop target item will be opened.
+        if (monitor.isOver()) {
+          setTimeout(() => {
+            if (monitor.isOver()) {
+              setIsOpen(true);
+            }
+          }, 600);
         }
-        else {
-          toastError(t('pagetree.something_went_wrong_with_moving_page'));
-        }
-      }
-    };
-
-    const [{ isOver }, drop] = useDrop<ItemNode, Promise<void>, { isOver: boolean }>(
-      () => ({
-        accept: 'PAGE_TREE',
-        drop: pageItemDropHandler,
-        hover: (item, monitor) => {
-          // when a drag item is overlapped more than 1 sec, the drop target item will be opened.
-          if (monitor.isOver()) {
-            setTimeout(() => {
-              if (monitor.isOver()) {
-                setIsOpen(true);
-              }
-            }, 600);
-          }
-        },
-        canDrop: (item) => {
-          const { page: droppedPage } = item;
-          return isDroppable(droppedPage, page);
-        },
-        collect: monitor => ({
-          isOver: monitor.isOver(),
-        }),
+      },
+      canDrop: (item) => {
+        const { page: droppedPage } = item;
+        return isDroppable(droppedPage, page);
+      },
+      collect: monitor => ({
+        isOver: monitor.isOver(),
       }),
-      [page],
-    );
-
-    // const memoizedDrag = useMemo(() => drag, []);
-    // const memoizedDrop = useMemo(() => drop, []);
-
-    const itemRef = (c) => { drag(c); drop(c) };
-
-    return (
-      <div className={shouldHide ? 'd-none' : ''}>
-        <SimpleItem
-          key={props.key}
-          targetPathOrId={props.targetPathOrId}
-          itemNode={props.itemNode}
-          isOpen
-          isEnableActions={props.isEnableActions}
-          isReadOnlyUser={props.isReadOnlyUser}
-          onRenamed={props.onRenamed}
-          onClickDuplicateMenuItem={props.onClickDuplicateMenuItem}
-          onClickDeleteMenuItem={props.onClickDeleteMenuItem}
-          // itemRef={itemRef}
-        />
-      </div>
-    );
-  };
+    }),
+    [page],
+  );
+
+  const itemRef = (c) => { drag(c); drop(c) };
+
+  const mainClassName = `${isOver ? 'grw-pagetree-is-over' : ''} ${shouldHide ? 'd-none' : ''}`;
+
+  return (
+    <SimpleItem
+      key={props.key}
+      targetPathOrId={props.targetPathOrId}
+      itemNode={props.itemNode}
+      isOpen
+      isEnableActions={props.isEnableActions}
+      isReadOnlyUser={props.isReadOnlyUser}
+      onRenamed={props.onRenamed}
+      onClickDuplicateMenuItem={props.onClickDuplicateMenuItem}
+      onClickDeleteMenuItem={props.onClickDeleteMenuItem}
+      itemRef={itemRef}
+      itemClass={PageTreeItem}
+      mainClassName={mainClassName}
+    />
+  );
 };

+ 23 - 164
apps/app/src/components/Sidebar/PageTree/SimpleItem.tsx

@@ -37,7 +37,6 @@ import { PageItemControl } from '../../Common/Dropdown/PageItemControl';
 
 import { ItemNode } from './ItemNode';
 
-
 const logger = loggerFactory('growi:cli:Item');
 
 
@@ -51,8 +50,12 @@ interface ItemProps {
   onClickDuplicateMenuItem?(pageToDuplicate: IPageForPageDuplicateModal): void
   onClickDeleteMenuItem?(pageToDelete: IPageToDeleteWithMeta): void
   itemRef?
+  itemClass?: React.FunctionComponent<ItemProps>
+  mainClassName?
 }
 
+// interface Item {}
+
 // Utility to mark target
 const markTarget = (children: ItemNode[], targetPathOrId?: Nullable<string>): void => {
   if (targetPathOrId == null) {
@@ -77,13 +80,6 @@ const markTarget = (children: ItemNode[], targetPathOrId?: Nullable<string>): vo
  * @returns
  */
 
-//
-const getNewPathAfterMoved = (droppedPagePath: string, newParentPagePath: string): string => {
-  const pageTitle = nodePath.basename(droppedPagePath);
-  return nodePath.join(newParentPagePath, pageTitle);
-};
-//
-
 /**
  * Return whether the fromPage could be moved under the newParentPage
  * @param fromPage
@@ -92,20 +88,6 @@ const getNewPathAfterMoved = (droppedPagePath: string, newParentPagePath: string
  * @returns
  */
 
-//
-const isDroppable = (fromPage?: Partial<IPageHasId>, newParentPage?: Partial<IPageHasId>, printLog = false): boolean => {
-  if (fromPage == null || newParentPage == null || fromPage.path == null || newParentPage.path == null) {
-    if (printLog) {
-      logger.warn('Any of page, page.path or droppedPage.path is null');
-    }
-    return false;
-  }
-
-  const newPathAfterMoved = getNewPathAfterMoved(fromPage.path, newParentPage.path);
-  return pagePathUtils.canMoveByPath(fromPage.path, newPathAfterMoved) && !pagePathUtils.isUsersTopPage(newParentPage.path);
-};
-//
-
 // Component wrapper to make a child element not draggable
 // https://github.com/react-dnd/react-dnd/issues/335
 type NotDraggableProps = {
@@ -147,120 +129,6 @@ const SimpleItem: FC<ItemProps> = (props: ItemProps) => {
   const isChildrenLoaded = currentChildren?.length > 0;
   const hasDescendants = descendantCount > 0 || isChildrenLoaded;
 
-  //
-  // to re-show hidden item when useDrag end() callback
-  const displayDroppedItemByPageId = useCallback((pageId) => {
-    const target = document.getElementById(`pagetree-item-${pageId}`);
-    if (target == null) {
-      return;
-    }
-
-    //   // wait 500ms to avoid removing before d-none is set by useDrag end() callback
-    setTimeout(() => {
-      target.classList.remove('d-none');
-    }, 500);
-  }, []);
-  //
-
-  // ここから切り分け開始
-  // const [, drag] = useDrag({
-  //   type: 'PAGE_TREE',
-  //   item: { page },
-  //   canDrag: () => {
-  //     if (page.path == null) {
-  //       return false;
-  //     }
-  //     return !pagePathUtils.isUsersProtectedPages(page.path);
-  //   },
-  //   end: (item, monitor) => {
-  //     // in order to set d-none to dropped Item
-  //     const dropResult = monitor.getDropResult();
-  //     if (dropResult != null) {
-  //       setShouldHide(true);
-  //     }
-  //   },
-  //   collect: monitor => ({
-  //     isDragging: monitor.isDragging(),
-  //     canDrag: monitor.canDrag(),
-  //   }),
-  // });
-  //
-
-  //
-  const pageItemDropHandler = async(item: ItemNode) => {
-    const { page: droppedPage } = item;
-
-    if (!isDroppable(droppedPage, page, true)) {
-      return;
-    }
-
-    if (droppedPage.path == null || page.path == null) {
-      return;
-    }
-
-    const newPagePath = getNewPathAfterMoved(droppedPage.path, page.path);
-
-    try {
-      await apiv3Put('/pages/rename', {
-        pageId: droppedPage._id,
-        revisionId: droppedPage.revision,
-        newPagePath,
-        isRenameRedirect: false,
-        updateMetadata: true,
-      });
-
-      await mutatePageTree();
-      await mutateChildren();
-
-      if (onRenamed != null) {
-        onRenamed(page.path, newPagePath);
-      }
-
-      // force open
-      setIsOpen(true);
-    }
-    catch (err) {
-      // display the dropped item
-      displayDroppedItemByPageId(droppedPage._id);
-
-      if (err.code === 'operation__blocked') {
-        toastWarning(t('pagetree.you_cannot_move_this_page_now'));
-      }
-      else {
-        toastError(t('pagetree.something_went_wrong_with_moving_page'));
-      }
-    }
-  };
-  //
-
-  //
-  // const [{ isOver }, drop] = useDrop<ItemNode, Promise<void>, { isOver: boolean }>(
-  //   () => ({
-  //     accept: 'PAGE_TREE',
-  //     drop: pageItemDropHandler,
-  //     hover: (item, monitor) => {
-  //       // when a drag item is overlapped more than 1 sec, the drop target item will be opened.
-  //       if (monitor.isOver()) {
-  //         setTimeout(() => {
-  //           if (monitor.isOver()) {
-  //             setIsOpen(true);
-  //           }
-  //         }, 600);
-  //       }
-  //     },
-  //     canDrop: (item) => {
-  //       const { page: droppedPage } = item;
-  //       return isDroppable(droppedPage, page);
-  //     },
-  //     collect: monitor => ({
-  //       isOver: monitor.isOver(),
-  //     }),
-  //   }),
-  //   [page],
-  // );
-  //
-
-
   const hasChildren = useCallback((): boolean => {
     return currentChildren != null && currentChildren.length > 0;
   }, [currentChildren]);
@@ -451,29 +319,27 @@ const SimpleItem: FC<ItemProps> = (props: ItemProps) => {
 
 
   const itemRef = props.itemRef;
+  const ItemClass = props.itemClass;
+  const ItemClassFixed = ItemClass ?? SimpleItem;
+  const mainClassName = props.mainClassName;
+
+  const commonProps = {
+    isEnableActions,
+    isReadOnlyUser,
+    isOpen: false,
+    targetPathOrId,
+    onRenamed,
+    onClickDuplicateMenuItem,
+    onClickDeleteMenuItem,
+  };
 
-  console.log(itemRef);
-
-  // const [isLoading, setIsLoading] = useState(true);
-
-  // useEffect(() => {
-  //   // someProp が非同期で設定されるまで待機
-  //   if (itemRef !== undefined) {
-  //     setIsLoading(false);
-  //   }
-  // }, [itemRef]);
-
-  // if (isLoading) {
-  //   return <div>Loading...</div>;
-  // }
-
-  // 上のやり方だと、意識的にitemRefを設定しなかった場合におかしくなる
+  console.log(mainClassName);
 
   return (
     <div
       id={`pagetree-item-${page._id}`}
       data-testid="grw-pagetree-item-container"
-      className={`grw-pagetree-item-container ${shouldHide ? 'd-none' : ''}`}
+      className={`grw-pagetree-item-container ${mainClassName}`}
     >
       <li
         ref={itemRef}
@@ -584,17 +450,10 @@ const SimpleItem: FC<ItemProps> = (props: ItemProps) => {
       {
         isOpen && hasChildren() && currentChildren.map((node, index) => (
           <div key={node.page._id} className="grw-pagetree-item-children">
-            <SimpleItem
-              isEnableActions={isEnableActions}
-              isReadOnlyUser={isReadOnlyUser}
-              itemNode={node}
-              isOpen={false}
-              targetPathOrId={targetPathOrId}
-              onRenamed={onRenamed}
-              onClickDuplicateMenuItem={onClickDuplicateMenuItem}
-              onClickDeleteMenuItem={onClickDeleteMenuItem}
-              itemRef={itemRef}
-            />
+            {/* itemClassに応じて、ここで生成するコンポーネントを変更する */}
+            {
+              <ItemClassFixed itemNode={node} {...commonProps} />
+            }
             {isCreating && (currentChildren.length - 1 === index) && (
               <div className="text-muted text-center">
                 <i className="fa fa-spinner fa-pulse mr-1"></i>