Yuki Takei 5 месяцев назад
Родитель
Сommit
b3716ad4f5

+ 1 - 1
apps/app/src/components/PageView/PageAlerts/PageGrantAlert.tsx

@@ -1,5 +1,5 @@
-import { isPopulated } from '@growi/core';
 import type { JSX } from 'react';
 import type { JSX } from 'react';
+import { isPopulated } from '@growi/core';
 import { useTranslation } from 'react-i18next';
 import { useTranslation } from 'react-i18next';
 
 
 import { useCurrentPageData } from '~/states/page';
 import { useCurrentPageData } from '~/states/page';

+ 2 - 1
apps/app/src/components/PageView/PageView.tsx

@@ -262,7 +262,8 @@ export const PageView = memo((props: Props): JSX.Element => {
     pagePath,
     pagePath,
     viewOptions,
     viewOptions,
     isSlide,
     isSlide,
-    isIdenticalPathPage, page
+    isIdenticalPathPage,
+    page,
   ]);
   ]);
 
 
   // DEBUG: Log final render completion time
   // DEBUG: Log final render completion time

+ 224 - 224
apps/app/src/pages/[[...path]]/index.page.tsx

@@ -1,286 +1,286 @@
-import { isClient } from "@growi/core/dist/utils";
-import EventEmitter from "events";
-import type { GetServerSideProps, GetServerSidePropsContext } from "next";
-import dynamic from "next/dynamic";
-import Head from "next/head";
-import type React from "react";
-import type { JSX, ReactNode } from "react";
-import { useEffect } from "react";
+import type React from 'react';
+import type { JSX, ReactNode } from 'react';
+import { useEffect } from 'react';
+import type { GetServerSideProps, GetServerSidePropsContext } from 'next';
+import dynamic from 'next/dynamic';
+import Head from 'next/head';
+import { isClient } from '@growi/core/dist/utils';
+import EventEmitter from 'events';
 
 
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { DescendantsPageListModalLazyLoaded } from "~/client/components/DescendantsPageListModal";
+import { DescendantsPageListModalLazyLoaded } from '~/client/components/DescendantsPageListModal';
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { ConflictDiffModalLazyLoaded } from "~/client/components/PageEditor/ConflictDiffModal";
+import { ConflictDiffModalLazyLoaded } from '~/client/components/PageEditor/ConflictDiffModal';
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { DrawioModalLazyLoaded } from "~/client/components/PageEditor/DrawioModal";
+import { DrawioModalLazyLoaded } from '~/client/components/PageEditor/DrawioModal';
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { HandsontableModalLazyLoaded } from "~/client/components/PageEditor/HandsontableModal";
+import { HandsontableModalLazyLoaded } from '~/client/components/PageEditor/HandsontableModal';
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { LinkEditModalLazyLoaded } from "~/client/components/PageEditor/LinkEditModal";
+import { LinkEditModalLazyLoaded } from '~/client/components/PageEditor/LinkEditModal';
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { TagEditModalLazyLoaded } from "~/client/components/PageTags/TagEditModal";
+import { TagEditModalLazyLoaded } from '~/client/components/PageTags/TagEditModal';
 // eslint-disable-next-line no-restricted-imports
 // eslint-disable-next-line no-restricted-imports
-import { TemplateModalLazyLoaded } from "~/client/components/TemplateModal";
-import { BasicLayout } from "~/components/Layout/BasicLayout";
-import { PageView } from "~/components/PageView/PageView";
-import { DrawioViewerScript } from "~/components/Script/DrawioViewerScript";
-import { useEditorModeClassName } from "~/services/layout/use-editor-mode-class-name";
-import { useCurrentPageData, useCurrentPagePath } from "~/states/page";
-import { useHydratePageAtoms } from "~/states/page/hydrate";
-import { useRendererConfig } from "~/states/server-configurations";
+import { TemplateModalLazyLoaded } from '~/client/components/TemplateModal';
+import { BasicLayout } from '~/components/Layout/BasicLayout';
+import { PageView } from '~/components/PageView/PageView';
+import { DrawioViewerScript } from '~/components/Script/DrawioViewerScript';
+import { useEditorModeClassName } from '~/services/layout/use-editor-mode-class-name';
+import { useCurrentPageData, useCurrentPagePath } from '~/states/page';
+import { useHydratePageAtoms } from '~/states/page/hydrate';
+import { useRendererConfig } from '~/states/server-configurations';
 import {
 import {
-	useSetupGlobalSocket,
-	useSetupGlobalSocketForPage,
-} from "~/states/socket-io";
-import { useSetEditingMarkdown } from "~/states/ui/editor";
-
-import type { NextPageWithLayout } from "../_app.page";
-import { useHydrateBasicLayoutConfigurationAtoms } from "../basic-layout-page/hydrate";
-import { getServerSideCommonEachProps } from "../common-props";
-import { useInitialCSRFetch } from "../general-page";
-import { useHydrateGeneralPageConfigurationAtoms } from "../general-page/hydrate";
-import { registerPageToShowRevisionWithMeta } from "../general-page/superjson";
+  useSetupGlobalSocket,
+  useSetupGlobalSocketForPage,
+} from '~/states/socket-io';
+import { useSetEditingMarkdown } from '~/states/ui/editor';
+
+import type { NextPageWithLayout } from '../_app.page';
+import { useHydrateBasicLayoutConfigurationAtoms } from '../basic-layout-page/hydrate';
+import { getServerSideCommonEachProps } from '../common-props';
+import { useInitialCSRFetch } from '../general-page';
+import { useHydrateGeneralPageConfigurationAtoms } from '../general-page/hydrate';
+import { registerPageToShowRevisionWithMeta } from '../general-page/superjson';
 import {
 import {
-	detectNextjsRoutingType,
-	NextjsRoutingType,
-} from "../utils/nextjs-routing-utils";
-import { useCustomTitleForPage } from "../utils/page-title-customization";
-import { mergeGetServerSidePropsResults } from "../utils/server-side-props";
-import { NEXT_JS_ROUTING_PAGE } from "./consts";
+  detectNextjsRoutingType,
+  NextjsRoutingType,
+} from '../utils/nextjs-routing-utils';
+import { useCustomTitleForPage } from '../utils/page-title-customization';
+import { mergeGetServerSidePropsResults } from '../utils/server-side-props';
+import { NEXT_JS_ROUTING_PAGE } from './consts';
 import {
 import {
-	getServerSidePropsForInitial,
-	getServerSidePropsForSameRoute,
-} from "./server-side-props";
-import type { EachProps, InitialProps } from "./types";
-import { useSameRouteNavigation } from "./use-same-route-navigation";
-import { useShallowRouting } from "./use-shallow-routing";
+  getServerSidePropsForInitial,
+  getServerSidePropsForSameRoute,
+} from './server-side-props';
+import type { EachProps, InitialProps } from './types';
+import { useSameRouteNavigation } from './use-same-route-navigation';
+import { useShallowRouting } from './use-shallow-routing';
 
 
 // call superjson custom register
 // call superjson custom register
 registerPageToShowRevisionWithMeta();
 registerPageToShowRevisionWithMeta();
 
 
 declare global {
 declare global {
-	// eslint-disable-next-line vars-on-top, no-var
-	var globalEmitter: EventEmitter;
+  // eslint-disable-next-line vars-on-top, no-var
+  var globalEmitter: EventEmitter;
 }
 }
 
 
 const GrowiContextualSubNavigation = dynamic(
 const GrowiContextualSubNavigation = dynamic(
-	() => import("~/client/components/Navbar/GrowiContextualSubNavigation"),
-	{ ssr: false },
+  () => import('~/client/components/Navbar/GrowiContextualSubNavigation'),
+  { ssr: false },
 );
 );
 
 
 const GrowiPluginsActivator = dynamic(
 const GrowiPluginsActivator = dynamic(
-	() =>
-		import(
-			"~/features/growi-plugin/client/components/GrowiPluginsActivator"
-		).then((mod) => mod.GrowiPluginsActivator),
-	{ ssr: false },
+  () =>
+    import(
+      '~/features/growi-plugin/client/components/GrowiPluginsActivator'
+    ).then((mod) => mod.GrowiPluginsActivator),
+  { ssr: false },
 );
 );
 
 
 const DisplaySwitcher = dynamic(
 const DisplaySwitcher = dynamic(
-	() =>
-		import("~/client/components/Page/DisplaySwitcher").then(
-			(mod) => mod.DisplaySwitcher,
-		),
-	{ ssr: false },
+  () =>
+    import('~/client/components/Page/DisplaySwitcher').then(
+      (mod) => mod.DisplaySwitcher,
+    ),
+  { ssr: false },
 );
 );
 const PageStatusAlert = dynamic(
 const PageStatusAlert = dynamic(
-	() =>
-		import("~/client/components/PageStatusAlert").then(
-			(mod) => mod.PageStatusAlert,
-		),
-	{ ssr: false },
+  () =>
+    import('~/client/components/PageStatusAlert').then(
+      (mod) => mod.PageStatusAlert,
+    ),
+  { ssr: false },
 );
 );
 
 
 const UnsavedAlertDialog = dynamic(
 const UnsavedAlertDialog = dynamic(
-	() => import("~/client/components/UnsavedAlertDialog"),
-	{ ssr: false },
+  () => import('~/client/components/UnsavedAlertDialog'),
+  { ssr: false },
 );
 );
 
 
 const EditablePageEffects = dynamic(
 const EditablePageEffects = dynamic(
-	() =>
-		import("~/client/components/Page/EditablePageEffects").then(
-			(mod) => mod.EditablePageEffects,
-		),
-	{ ssr: false },
+  () =>
+    import('~/client/components/Page/EditablePageEffects').then(
+      (mod) => mod.EditablePageEffects,
+    ),
+  { ssr: false },
 );
 );
 
 
 type Props = EachProps | InitialProps;
 type Props = EachProps | InitialProps;
 
 
 const isInitialProps = (props: Props): props is InitialProps => {
 const isInitialProps = (props: Props): props is InitialProps => {
-	return (
-		"isNextjsRoutingTypeInitial" in props && props.isNextjsRoutingTypeInitial
-	);
+  return (
+    'isNextjsRoutingTypeInitial' in props && props.isNextjsRoutingTypeInitial
+  );
 };
 };
 
 
 const Page: NextPageWithLayout<Props> = (props: Props) => {
 const Page: NextPageWithLayout<Props> = (props: Props) => {
-	// register global EventEmitter
-	if (isClient() && window.globalEmitter == null) {
-		window.globalEmitter = new EventEmitter();
-	}
-
-	// Initialize Jotai atoms with initial data - must be called unconditionally
-	const pageData = isInitialProps(props) ? props.pageWithMeta?.data : undefined;
-	const pageMeta = isInitialProps(props) ? props.pageWithMeta?.meta : undefined;
-
-	useHydratePageAtoms(pageData, pageMeta, {
-		redirectFrom: props.redirectFrom ?? undefined,
-		templateTags: props.templateTagData,
-		templateBody: props.templateBodyData,
-	});
-
-	const currentPage = useCurrentPageData();
-	const currentPagePath = useCurrentPagePath();
-	const rendererConfig = useRendererConfig();
-	const setEditingMarkdown = useSetEditingMarkdown();
-
-	// setup socket.io
-	useSetupGlobalSocket();
-	useSetupGlobalSocketForPage();
-
-	// Use custom hooks for navigation and routing
-	useSameRouteNavigation();
-	useShallowRouting(props);
-
-	// If initial props and skipSSR, fetch page data on client-side
-	useInitialCSRFetch(isInitialProps(props) && props.skipSSR);
-
-	useEffect(() => {
-		// Initialize editing markdown only when page path changes
-		if (currentPagePath) {
-			setEditingMarkdown(currentPage?.revision?.body || "");
-		}
-	}, [currentPagePath, currentPage?.revision?.body, setEditingMarkdown]);
-
-	// If the data on the page changes without router.push, pageWithMeta remains old because getServerSideProps() is not executed
-	// So preferentially take page data from useSWRxCurrentPage
-	const pagePath = currentPagePath ?? props.currentPathname;
-
-	const title = useCustomTitleForPage(pagePath);
-
-	return (
-		<>
-			<Head>
-				<title>{title}</title>
-			</Head>
-			<div className="dynamic-layout-root justify-content-between">
-				<GrowiContextualSubNavigation currentPage={currentPage} />
-
-				<PageView
-					className="d-edit-none"
-					pagePath={pagePath}
-					rendererConfig={rendererConfig}
-				/>
-
-				<EditablePageEffects />
-				<DisplaySwitcher />
-
-				<PageStatusAlert />
-			</div>
-		</>
-	);
+  // register global EventEmitter
+  if (isClient() && window.globalEmitter == null) {
+    window.globalEmitter = new EventEmitter();
+  }
+
+  // Initialize Jotai atoms with initial data - must be called unconditionally
+  const pageData = isInitialProps(props) ? props.pageWithMeta?.data : undefined;
+  const pageMeta = isInitialProps(props) ? props.pageWithMeta?.meta : undefined;
+
+  useHydratePageAtoms(pageData, pageMeta, {
+    redirectFrom: props.redirectFrom ?? undefined,
+    templateTags: props.templateTagData,
+    templateBody: props.templateBodyData,
+  });
+
+  const currentPage = useCurrentPageData();
+  const currentPagePath = useCurrentPagePath();
+  const rendererConfig = useRendererConfig();
+  const setEditingMarkdown = useSetEditingMarkdown();
+
+  // setup socket.io
+  useSetupGlobalSocket();
+  useSetupGlobalSocketForPage();
+
+  // Use custom hooks for navigation and routing
+  useSameRouteNavigation();
+  useShallowRouting(props);
+
+  // If initial props and skipSSR, fetch page data on client-side
+  useInitialCSRFetch(isInitialProps(props) && props.skipSSR);
+
+  useEffect(() => {
+    // Initialize editing markdown only when page path changes
+    if (currentPagePath) {
+      setEditingMarkdown(currentPage?.revision?.body || '');
+    }
+  }, [currentPagePath, currentPage?.revision?.body, setEditingMarkdown]);
+
+  // If the data on the page changes without router.push, pageWithMeta remains old because getServerSideProps() is not executed
+  // So preferentially take page data from useSWRxCurrentPage
+  const pagePath = currentPagePath ?? props.currentPathname;
+
+  const title = useCustomTitleForPage(pagePath);
+
+  return (
+    <>
+      <Head>
+        <title>{title}</title>
+      </Head>
+      <div className="dynamic-layout-root justify-content-between">
+        <GrowiContextualSubNavigation currentPage={currentPage} />
+
+        <PageView
+          className="d-edit-none"
+          pagePath={pagePath}
+          rendererConfig={rendererConfig}
+        />
+
+        <EditablePageEffects />
+        <DisplaySwitcher />
+
+        <PageStatusAlert />
+      </div>
+    </>
+  );
 };
 };
 
 
 const BasicLayoutWithEditor = ({
 const BasicLayoutWithEditor = ({
-	children,
+  children,
 }: {
 }: {
-	children?: ReactNode;
+  children?: ReactNode;
 }): JSX.Element => {
 }): JSX.Element => {
-	const editorModeClassName = useEditorModeClassName();
-	return <BasicLayout className={editorModeClassName}>{children}</BasicLayout>;
+  const editorModeClassName = useEditorModeClassName();
+  return <BasicLayout className={editorModeClassName}>{children}</BasicLayout>;
 };
 };
 
 
 type LayoutProps = Props & {
 type LayoutProps = Props & {
-	children?: ReactNode;
+  children?: ReactNode;
 };
 };
 
 
 const Layout = ({ children, ...props }: LayoutProps): JSX.Element => {
 const Layout = ({ children, ...props }: LayoutProps): JSX.Element => {
-	// Hydrate sidebar atoms with server-side data - must be called unconditionally
-	const initialProps = isInitialProps(props) ? props : undefined;
-	useHydrateBasicLayoutConfigurationAtoms(
-		initialProps?.searchConfig,
-		initialProps?.sidebarConfig,
-		initialProps?.userUISettings,
-	);
-	useHydrateGeneralPageConfigurationAtoms(
-		initialProps?.serverConfig,
-		initialProps?.rendererConfig,
-	);
-
-	return <BasicLayoutWithEditor>{children}</BasicLayoutWithEditor>;
+  // Hydrate sidebar atoms with server-side data - must be called unconditionally
+  const initialProps = isInitialProps(props) ? props : undefined;
+  useHydrateBasicLayoutConfigurationAtoms(
+    initialProps?.searchConfig,
+    initialProps?.sidebarConfig,
+    initialProps?.userUISettings,
+  );
+  useHydrateGeneralPageConfigurationAtoms(
+    initialProps?.serverConfig,
+    initialProps?.rendererConfig,
+  );
+
+  return <BasicLayoutWithEditor>{children}</BasicLayoutWithEditor>;
 };
 };
 
 
 Page.getLayout = function getLayout(page: React.ReactElement<Props>) {
 Page.getLayout = function getLayout(page: React.ReactElement<Props>) {
-	// Get drawioUri from rendererConfig atom to ensure consistency across navigations
-	const DrawioViewerScriptWithAtom = (): JSX.Element => {
-		const rendererConfig = useRendererConfig();
-		return <DrawioViewerScript drawioUri={rendererConfig.drawioUri} />;
-	};
-
-	return (
-		<>
-			<GrowiPluginsActivator />
-			<DrawioViewerScriptWithAtom />
-
-			<Layout {...page.props}>{page}</Layout>
-			<UnsavedAlertDialog />
-			<DescendantsPageListModalLazyLoaded />
-			<DrawioModalLazyLoaded />
-			<HandsontableModalLazyLoaded />
-			<TemplateModalLazyLoaded />
-			<LinkEditModalLazyLoaded />
-			<TagEditModalLazyLoaded />
-			<ConflictDiffModalLazyLoaded />
-		</>
-	);
+  // Get drawioUri from rendererConfig atom to ensure consistency across navigations
+  const DrawioViewerScriptWithAtom = (): JSX.Element => {
+    const rendererConfig = useRendererConfig();
+    return <DrawioViewerScript drawioUri={rendererConfig.drawioUri} />;
+  };
+
+  return (
+    <>
+      <GrowiPluginsActivator />
+      <DrawioViewerScriptWithAtom />
+
+      <Layout {...page.props}>{page}</Layout>
+      <UnsavedAlertDialog />
+      <DescendantsPageListModalLazyLoaded />
+      <DrawioModalLazyLoaded />
+      <HandsontableModalLazyLoaded />
+      <TemplateModalLazyLoaded />
+      <LinkEditModalLazyLoaded />
+      <TagEditModalLazyLoaded />
+      <ConflictDiffModalLazyLoaded />
+    </>
+  );
 };
 };
 
 
 export const getServerSideProps: GetServerSideProps<Props> = async (
 export const getServerSideProps: GetServerSideProps<Props> = async (
-	context: GetServerSidePropsContext,
+  context: GetServerSidePropsContext,
 ) => {
 ) => {
-	//
-	// STAGE 1
-	//
-
-	const commonEachPropsResult = await getServerSideCommonEachProps(
-		context,
-		NEXT_JS_ROUTING_PAGE,
-	);
-	// Handle early return cases (redirect/notFound)
-	if (
-		"redirect" in commonEachPropsResult ||
-		"notFound" in commonEachPropsResult
-	) {
-		return commonEachPropsResult;
-	}
-	const commonEachProps = await commonEachPropsResult.props;
-
-	// Handle redirect destination from common props
-	if (commonEachProps.redirectDestination != null) {
-		return {
-			redirect: {
-				permanent: false,
-				destination: commonEachProps.redirectDestination,
-			},
-		};
-	}
-
-	//
-	// STAGE 2
-	//
-
-	// detect Next.js routing type
-	const nextjsRoutingType = detectNextjsRoutingType(
-		context,
-		NEXT_JS_ROUTING_PAGE,
-	);
-
-	// Merge all results in a type-safe manner (using sequential merging)
-	return mergeGetServerSidePropsResults(
-		commonEachPropsResult,
-		nextjsRoutingType === NextjsRoutingType.INITIAL
-			? await getServerSidePropsForInitial(context)
-			: await getServerSidePropsForSameRoute(context),
-	);
+  //
+  // STAGE 1
+  //
+
+  const commonEachPropsResult = await getServerSideCommonEachProps(
+    context,
+    NEXT_JS_ROUTING_PAGE,
+  );
+  // Handle early return cases (redirect/notFound)
+  if (
+    'redirect' in commonEachPropsResult ||
+    'notFound' in commonEachPropsResult
+  ) {
+    return commonEachPropsResult;
+  }
+  const commonEachProps = await commonEachPropsResult.props;
+
+  // Handle redirect destination from common props
+  if (commonEachProps.redirectDestination != null) {
+    return {
+      redirect: {
+        permanent: false,
+        destination: commonEachProps.redirectDestination,
+      },
+    };
+  }
+
+  //
+  // STAGE 2
+  //
+
+  // detect Next.js routing type
+  const nextjsRoutingType = detectNextjsRoutingType(
+    context,
+    NEXT_JS_ROUTING_PAGE,
+  );
+
+  // Merge all results in a type-safe manner (using sequential merging)
+  return mergeGetServerSidePropsResults(
+    commonEachPropsResult,
+    nextjsRoutingType === NextjsRoutingType.INITIAL
+      ? await getServerSidePropsForInitial(context)
+      : await getServerSidePropsForSameRoute(context),
+  );
 };
 };
 
 
 export default Page;
 export default Page;