WNomunomu пре 2 година
родитељ
комит
3f701ec69b

+ 149 - 0
apps/app/src/components/Sidebar/PageTree/PageTreeItem.tsx

@@ -0,0 +1,149 @@
+import React, { useCallback } from 'react';
+
+import nodePath from 'path';
+
+import { pagePathUtils } from '@growi/core';
+import { useDrag, useDrop } from 'react-dnd';
+
+import { apiv3Put } from '~/client/util/apiv3-client';
+import { toastWarning, toastError } from '~/client/util/toastr';
+import { IPageHasId } from '~/interfaces/page';
+import { mutatePageTree } from '~/stores/page-listing';
+import loggerFactory from '~/utils/logger';
+
+import { ItemNode } from './ItemNode';
+
+
+const logger = loggerFactory('growi:cli:Item');
+
+
+export const CreatePageTreeItem = (SimpleItem) => {
+  const settings = '';
+
+  return function pageTreeItem() {
+    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);
+    };
+    // 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],
+    );
+
+    return (
+      <SimpleItem settings={settings}/>
+    );
+  };
+};

+ 123 - 121
apps/app/src/components/Sidebar/PageTree/SimpleItem.tsx

@@ -75,10 +75,10 @@ const markTarget = (children: ItemNode[], targetPathOrId?: Nullable<string>): vo
  * @param newParentPagePath
  * @returns
  */
-const getNewPathAfterMoved = (droppedPagePath: string, newParentPagePath: string): string => {
-  const pageTitle = nodePath.basename(droppedPagePath);
-  return nodePath.join(newParentPagePath, pageTitle);
-};
+// 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
@@ -87,17 +87,17 @@ const getNewPathAfterMoved = (droppedPagePath: string, newParentPagePath: string
  * @param printLog
  * @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);
-};
+// 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
@@ -141,109 +141,109 @@ const SimpleItem: FC<ItemProps> = (props: ItemProps) => {
   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 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 => {
@@ -438,11 +438,11 @@ const SimpleItem: FC<ItemProps> = (props: ItemProps) => {
     <div
       id={`pagetree-item-${page._id}`}
       data-testid="grw-pagetree-item-container"
-      className={`grw-pagetree-item-container ${isOver ? 'grw-pagetree-is-over' : ''}
-      ${shouldHide ? 'd-none' : ''}`}
+      className={`grw-pagetree-item-container ${shouldHide ? 'd-none' : ''}`}
     >
       <li
         // ref={(c) => { drag(c); drop(c) }}
+        { props.hoge ?? '' }
         className={`list-group-item list-group-item-action border-0 py-0 pr-3 d-flex align-items-center
         ${page.isTarget ? 'grw-pagetree-current-page-item' : ''}`}
         id={page.isTarget ? 'grw-pagetree-current-page-item' : `grw-pagetree-list-${page._id}`}
@@ -485,7 +485,9 @@ const SimpleItem: FC<ItemProps> = (props: ItemProps) => {
                 </>
               )}
               {page != null && page.path != null && page._id != null && (
-                <p onClick={pageTreeItemClickHandler} className={`text-truncate m-auto ${page.isEmpty && 'grw-sidebar-text-muted'}`}>{pageName}</p>
+                <div className="grw-pagetree-title-anchor flex-grow-1">
+                  <p onClick={pageTreeItemClickHandler} className={`text-truncate m-auto ${page.isEmpty && 'grw-sidebar-text-muted'}`}>{pageName}</p>
+                </div>
               )}
             </>
           )}