Kaynağa Gözat

use suspense

Yuki Takei 2 yıl önce
ebeveyn
işleme
90e50a53df

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

@@ -0,0 +1,32 @@
+import { Suspense } from 'react';
+
+import dynamic from 'next/dynamic';
+import { useTranslation } from 'react-i18next';
+
+import PageTreeContentSkeleton from './PageTreeContentSkeleton';
+import { PageTreeHeader } from './PageTreeSubstance';
+
+const PageTreeContent = dynamic(
+  () => import('./PageTreeSubstance').then(mod => mod.PageTreeContent),
+  { ssr: false, loading: PageTreeContentSkeleton },
+);
+
+
+export const PageTree = (): JSX.Element => {
+  const { t } = useTranslation();
+
+  return (
+    <div className="px-3">
+      <div className="grw-sidebar-content-header py-3 d-flex">
+        <h3 className="mb-0">{t('Page Tree')}</h3>
+        <Suspense>
+          <PageTreeHeader />
+        </Suspense>
+      </div>
+
+      <Suspense fallback={<PageTreeContentSkeleton />}>
+        <PageTreeContent />
+      </Suspense>
+    </div>
+  );
+};

+ 29 - 21
apps/app/src/components/Sidebar/PageTree/PageTreeSubstance.tsx

@@ -1,14 +1,35 @@
-import React, { memo } from 'react';
+import React, { memo, useCallback } from 'react';
 
 
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 
 
 import { useTargetAndAncestors, useIsGuestUser, useIsReadOnlyUser } from '~/stores/context';
 import { useTargetAndAncestors, useIsGuestUser, useIsReadOnlyUser } from '~/stores/context';
 import { useCurrentPagePath, useCurrentPageId } from '~/stores/page';
 import { useCurrentPagePath, useCurrentPageId } from '~/stores/page';
-import { useSWRxV5MigrationStatus } from '~/stores/page-listing';
+import { mutatePageTree, useSWRxRootPage, useSWRxV5MigrationStatus } from '~/stores/page-listing';
+
+import { SidebarHeaderReloadButton } from '../SidebarHeaderReloadButton';
 
 
 import ItemsTree from './ItemsTree';
 import ItemsTree from './ItemsTree';
 import { PrivateLegacyPagesLink } from './PrivateLegacyPagesLink';
 import { PrivateLegacyPagesLink } from './PrivateLegacyPagesLink';
 
 
+
+export const PageTreeHeader = memo(() => {
+  const { mutate: mutateRootPage } = useSWRxRootPage({ suspense: true });
+  useSWRxV5MigrationStatus({ suspense: true });
+
+  const mutate = useCallback(() => {
+    mutateRootPage();
+    mutatePageTree();
+  }, [mutateRootPage]);
+
+  return (
+    <>
+      <SidebarHeaderReloadButton onClick={() => mutate()}/>
+    </>
+  );
+});
+PageTreeHeader.displayName = 'PageTreeHeader';
+
+
 const PageTreeUnavailable = () => {
 const PageTreeUnavailable = () => {
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 
@@ -22,29 +43,19 @@ const PageTreeUnavailable = () => {
   );
   );
 };
 };
 
 
-export const PageTreeSubstance = memo(() => {
-  const { t } = useTranslation();
-
+export const PageTreeContent = memo(() => {
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isGuestUser } = useIsGuestUser();
   const { data: isReadOnlyUser } = useIsReadOnlyUser();
   const { data: isReadOnlyUser } = useIsReadOnlyUser();
   const { data: currentPath } = useCurrentPagePath();
   const { data: currentPath } = useCurrentPagePath();
   const { data: targetId } = useCurrentPageId();
   const { data: targetId } = useCurrentPageId();
   const { data: targetAndAncestorsData } = useTargetAndAncestors();
   const { data: targetAndAncestorsData } = useTargetAndAncestors();
 
 
-  const { data: migrationStatus } = useSWRxV5MigrationStatus();
+  const { data: migrationStatus } = useSWRxV5MigrationStatus({ suspense: true });
 
 
   const targetPathOrId = targetId || currentPath;
   const targetPathOrId = targetId || currentPath;
 
 
   if (!migrationStatus?.isV5Compatible) {
   if (!migrationStatus?.isV5Compatible) {
-
-    return (
-      <div className="px-3">
-        <div className="grw-sidebar-content-header py-3 d-flex">
-          <h3 className="mb-0">{t('Page Tree')}</h3>
-        </div>
-        <PageTreeUnavailable />
-      </div>
-    );
+    return <PageTreeUnavailable />;
   }
   }
 
 
   /*
   /*
@@ -57,10 +68,7 @@ export const PageTreeSubstance = memo(() => {
   const path = currentPath || '/';
   const path = currentPath || '/';
 
 
   return (
   return (
-    <div className="px-3">
-      <div className="grw-sidebar-content-header py-3 d-flex">
-        <h3 className="mb-0">{t('Page Tree')}</h3>
-      </div>
+    <>
       <ItemsTree
       <ItemsTree
         isEnableActions={!isGuestUser}
         isEnableActions={!isGuestUser}
         isReadOnlyUser={!!isReadOnlyUser}
         isReadOnlyUser={!!isReadOnlyUser}
@@ -76,8 +84,8 @@ export const PageTreeSubstance = memo(() => {
           </div>
           </div>
         </div>
         </div>
       )}
       )}
-    </div>
+    </>
   );
   );
 });
 });
 
 
-PageTreeSubstance.displayName = 'PageTreeSubstance';
+PageTreeContent.displayName = 'PageTreeContent';

+ 7 - 4
apps/app/src/stores/page-listing.tsx

@@ -134,8 +134,8 @@ export const useSWRxPageInfoForList = (
   };
   };
 };
 };
 
 
-export const useSWRxRootPage = (): SWRResponse<RootPageResult, Error> => {
-  return useSWRImmutable(
+export const useSWRxRootPage = (config?: SWRConfiguration): SWRResponse<RootPageResult, Error> => {
+  return useSWR(
     '/page-listing/root',
     '/page-listing/root',
     endpoint => apiv3Get(endpoint).then((response) => {
     endpoint => apiv3Get(endpoint).then((response) => {
       return {
       return {
@@ -143,7 +143,10 @@ export const useSWRxRootPage = (): SWRResponse<RootPageResult, Error> => {
       };
       };
     }),
     }),
     {
     {
+      ...config,
       keepPreviousData: true,
       keepPreviousData: true,
+      revalidateOnFocus: false,
+      revalidateOnReconnect: false,
     },
     },
   );
   );
 };
 };
@@ -203,8 +206,7 @@ export const useSWRxPageChildren = (
   );
   );
 };
 };
 
 
-export const useSWRxV5MigrationStatus = (
-): SWRResponse<V5MigrationStatus, Error> => {
+export const useSWRxV5MigrationStatus = (config?: SWRConfiguration): SWRResponse<V5MigrationStatus, Error> => {
   return useSWRImmutable(
   return useSWRImmutable(
     '/pages/v5-migration-status',
     '/pages/v5-migration-status',
     endpoint => apiv3Get(endpoint).then((response) => {
     endpoint => apiv3Get(endpoint).then((response) => {
@@ -213,5 +215,6 @@ export const useSWRxV5MigrationStatus = (
         migratablePagesCount: response.data.migratablePagesCount,
         migratablePagesCount: response.data.migratablePagesCount,
       };
       };
     }),
     }),
+    config,
   );
   );
 };
 };