Taichi Masuyama 4 سال پیش
والد
کامیت
58c053aae9

+ 26 - 8
packages/app/src/components/Sidebar/PageTree/Item.tsx

@@ -1,5 +1,7 @@
-import React, { memo } from 'react';
+import React, { memo, useCallback, useState } from 'react';
+
 import { ItemNode } from './ItemNode';
+import { useSWRxPageChildren } from '../../../stores/page-listing';
 
 
 interface ItemProps {
@@ -7,11 +9,29 @@ interface ItemProps {
   isOpen?: boolean
 }
 
-const Item = memo<ItemProps>((props: ItemProps) => {
+const Item = (props: ItemProps) => {
   const { itemNode, isOpen = false } = props;
 
   const { page, children } = itemNode;
 
+  const [currentChildren, setCurrentChildren] = useState(children);
+
+  const [shouldFetch, setShouldFetch] = useState(false);
+  const { data, error } = useSWRxPageChildren(shouldFetch ? page._id : null);
+
+  const hasChildren = useCallback((): boolean => {
+    return currentChildren != null && currentChildren?.length > 0;
+  }, [currentChildren]);
+
+  const onClickLoadChildren = useCallback(() => {
+    setShouldFetch(true);
+  }, []);
+
+  if (error == null && data != null) {
+    const { children } = data;
+    setCurrentChildren(ItemNode.generateNodesFromPages(children));
+  }
+
   if (page == null) {
     return null;
   }
@@ -20,14 +40,12 @@ const Item = memo<ItemProps>((props: ItemProps) => {
   const style = { margin: '10px', opacity: 1.0 };
   if (page.isTarget) style.opacity = 0.7;
 
-  /*
-   * Normal render
-   */
+  console.log('すべて', hasChildren(), currentChildren, itemNode);
   return (
     <div style={style}>
-      <p>{page.path}</p>
+      <p>{page.path} <button type="button" onClick={onClickLoadChildren}>Load</button></p>
       {
-        itemNode.hasChildren() && (children as ItemNode[]).map(node => (
+        hasChildren() && currentChildren.map(node => (
           <Item
             key={node.page._id}
             itemNode={node}
@@ -38,6 +56,6 @@ const Item = memo<ItemProps>((props: ItemProps) => {
     </div>
   );
 
-});
+};
 
 export default Item;

+ 1 - 8
packages/app/src/components/Sidebar/PageTree/ItemNode.ts

@@ -1,7 +1,4 @@
-import { IPage } from '../../../interfaces/page';
-import { HasObjectId } from '../../../interfaces/has-object-id';
-
-type IPageForItem = Partial<IPage & {isTarget?: boolean} & HasObjectId>;
+import { IPageForItem } from '../../../interfaces/page';
 
 export class ItemNode {
 
@@ -14,10 +11,6 @@ export class ItemNode {
     this.children = children;
   }
 
-  hasChildren(): boolean {
-    return this.children != null && this.children?.length > 0;
-  }
-
   static generateNodesFromPages(pages: IPageForItem[]): ItemNode[] {
     return pages.map(page => new ItemNode(page));
   }

+ 7 - 4
packages/app/src/interfaces/page-listing-results.ts

@@ -1,10 +1,13 @@
-import { IPage } from './page';
-import { HasObjectId } from './has-object-id';
+import { IPageForItem } from './page';
 
 
 type ParentPath = string;
 export interface AncestorsChildrenResult {
-  ancestorsChildren: Record<ParentPath, Partial<IPage & HasObjectId>[]>
+  ancestorsChildren: Record<ParentPath, Partial<IPageForItem>[]>
 }
 
-export type TargetAndAncestors = Partial<IPage & HasObjectId>[];
+export type TargetAndAncestors = Partial<IPageForItem>[];
+
+export interface ChildrenResult {
+  children: Partial<IPageForItem>[]
+}

+ 3 - 0
packages/app/src/interfaces/page.ts

@@ -2,6 +2,7 @@ import { Ref } from './common';
 import { IUser } from './user';
 import { IRevision } from './revision';
 import { ITag } from './tag';
+import { HasObjectId } from './has-object-id';
 
 
 export type IPage = {
@@ -29,3 +30,5 @@ export type IPage = {
   deleteUser: Ref<IUser>,
   deletedAt: Date,
 }
+
+export type IPageForItem = Partial<IPage & {isTarget?: boolean} & HasObjectId>;

+ 15 - 1
packages/app/src/stores/page-listing.tsx

@@ -1,7 +1,7 @@
 import useSWR, { SWRResponse } from 'swr';
 
 import { apiv3Get } from '../client/util/apiv3-client';
-import { AncestorsChildrenResult } from '../interfaces/page-listing-results';
+import { AncestorsChildrenResult, ChildrenResult } from '../interfaces/page-listing-results';
 
 
 export const useSWRxPageAncestorsChildren = (
@@ -16,3 +16,17 @@ export const useSWRxPageAncestorsChildren = (
     }),
   );
 };
+
+
+export const useSWRxPageChildren = (
+    id: string | null,
+): SWRResponse<ChildrenResult, Error> => {
+  return useSWR(
+    id ? `/page-listing/children?id=${id}` : null,
+    endpoint => apiv3Get(endpoint).then((response) => {
+      return {
+        children: response.data.children,
+      };
+    }),
+  );
+};